wpCentral - Version 1.0

Version Description

Download this release

Release Info

Developer softacpriya
Plugin Icon 128x128 wpCentral
Version 1.0
Comparing to
See all releases

Version 1.0

Files changed (9) hide show
  1. actions.php +275 -0
  2. file_actions.php +59 -0
  3. get_site_data.php +46 -0
  4. readme.txt +39 -0
  5. verify.php +41 -0
  6. wpc_functions.php +2319 -0
  7. wpc_soft_pclzip.php +1531 -0
  8. wpcentral.php +63 -0
  9. wpcentral_lang.php +31 -0
actions.php ADDED
@@ -0,0 +1,275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (!defined('ABSPATH')){
4
+ exit;
5
+ }
6
+
7
+ function wpc_site_actions(){
8
+ global $l, $error, $wp_config;
9
+
10
+ $return = array();
11
+
12
+ $request = wpc_optREQ('request');
13
+
14
+ if(empty($request)){
15
+ $return['error'] = $l['no_req_post'];
16
+ echo json_encode($return);
17
+ die();
18
+ }
19
+
20
+ if($request == 'update_website'){
21
+ $source = urldecode(wpc_optREQ('source'));
22
+
23
+ include_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php');
24
+ include_once(ABSPATH.'wp-admin/includes/update.php');
25
+ include_once(ABSPATH.'wp-admin/includes/misc.php');
26
+
27
+ global $wp_filesystem;
28
+
29
+ $upgrade_error = array();
30
+
31
+ $wp_upgrader_skin = new WP_Upgrader_Skin();
32
+ $wp_upgrader_skin->done_header = true;
33
+
34
+ $wp_upgrader = new WP_Upgrader($wp_upgrader_skin);
35
+
36
+ $res = $wp_upgrader->fs_connect(array(get_home_path(), WP_CONTENT_DIR));
37
+ if (!$res || is_wp_error($res)){
38
+ $upgrade_error[] = $res;
39
+ }
40
+
41
+ $download = $wp_upgrader->download_package($source);
42
+ if (is_wp_error($download)){
43
+ $upgrade_error[] = $download;
44
+ }
45
+
46
+ $working_dir = $wp_upgrader->unpack_package($download);
47
+ if (is_wp_error($working_dir)){
48
+ $upgrade_error[] = $working_dir;
49
+ }
50
+
51
+ $wp_dir = trailingslashit($wp_filesystem->abspath());
52
+
53
+ if (!$wp_filesystem->copy($working_dir.'/wordpress/wp-admin/includes/update-core.php', $wp_dir.'wp-admin/includes/update-core.php', true)){
54
+ $wp_filesystem->delete($working_dir, true);
55
+
56
+ $upgrade_error[] = $l['copy_fail'];
57
+ }
58
+
59
+ $wp_filesystem->chmod($wp_dir.'wp-admin/includes/update-core.php', FS_CHMOD_FILE);
60
+ include_once(get_home_path().'wp-admin/includes/update-core.php');
61
+
62
+ if(!function_exists('update_core')){
63
+ $upgrade_error[] = $l['call_update_fail'];
64
+ }
65
+
66
+ $result = update_core($working_dir, $wp_dir);
67
+ if(is_wp_error($result)){
68
+ $upgrade_error[] = $result->get_error_code();
69
+ }
70
+
71
+ if(!empty($upgrade_error)){
72
+ $return['error'] = 'error: '.implode("\n", $upgrade_error);
73
+ }
74
+ }
75
+
76
+ if(wpc_optGET('plugins') || wpc_optGET('plugin')){
77
+ $plugins = urldecode($_REQUEST['plugins']);
78
+ $arr_plugins = explode(',', $plugins);
79
+
80
+ if($request == 'activate'){//Activate
81
+
82
+ $res = wpc_activate_plugin($arr_plugins);
83
+ if(!$res){
84
+ $return['error'] = $l['err_activating_pl'];
85
+ }
86
+ }elseif($request == 'deactivate'){//Deactivate
87
+
88
+ $res = wpc_deactivate_plugin($arr_plugins);
89
+ if(!$res){
90
+ $return['error'] = $l['err_deactivating_pl'];
91
+ }
92
+ }elseif($request == 'delete'){//Deactivate and then Delete
93
+
94
+ $act_res = wpc_deactivate_plugin($arr_plugins);
95
+ if(!$act_res){
96
+ $return['error'] = $l['err_deactivating_del_pl'];
97
+ }
98
+
99
+ $result = delete_plugins($arr_plugins);
100
+ if(is_wp_error($result)) {
101
+ $return['error'] = $result->get_error_message();
102
+ }elseif($result === false) {
103
+ $return['error'] = $l['err_deleting_pl'];
104
+ }
105
+ }elseif($request == 'install'){//Install Plugins
106
+
107
+ $sources = urldecode($_REQUEST['sources']);
108
+ $arr_sources = explode(',', $sources);
109
+
110
+ foreach($arr_plugins as $plk => $plval){
111
+
112
+ //Skip if the plugin is already installed
113
+ if(wpc_is_plugin_installed($plval)){
114
+ continue;
115
+ }
116
+
117
+ $filename = basename(parse_url($arr_sources[$plk], PHP_URL_PATH));
118
+
119
+ $download_dest = $wp_config['uploads_dir'].'/'.$filename;
120
+ $unzip_dest = $wp_config['plugins_root_dir'];
121
+
122
+ wpc_get_web_file($arr_sources[$plk], $download_dest);
123
+
124
+ if(wpc_sfile_exists($download_dest)){
125
+ $res = wpc_unzip($download_dest, $unzip_dest);
126
+ }
127
+
128
+ @wpc_sunlink($download_dest);
129
+
130
+ //Activate the installed plugin
131
+ $all_installed_plugins = wpc_get_plugins();
132
+ $slugs = array_keys($all_installed_plugins);
133
+
134
+ $plugin_slug = '';
135
+ //Fetch slug of the installed plugin
136
+ foreach($slugs as $val){
137
+ if(strpos($val, $plval) !== false){
138
+ $plugin_slug = $val;
139
+ break;
140
+ }
141
+ }
142
+
143
+ wpc_activate_plugin(array($plugin_slug));
144
+ }
145
+
146
+ if(!empty($error)){
147
+ $return['error'] = $error;
148
+ }
149
+ }elseif($request == 'update'){
150
+
151
+ $plugin_name = urldecode(wpc_optREQ('plugin'));
152
+ $download_link = urldecode(wpc_optREQ('source'));
153
+ $site_url = urldecode(wpc_optREQ('siteurl'));
154
+
155
+ $filename = basename(parse_url($download_link, PHP_URL_PATH));
156
+
157
+ $download_dest = $wp_config['uploads_dir'].'/'.$filename;
158
+ $unzip_dest = $wp_config['plugins_root_dir'];
159
+
160
+ wpc_get_web_file($download_link, $download_dest);
161
+
162
+ if(wpc_sfile_exists($download_dest)){
163
+ $res = wpc_unzip($download_dest, $unzip_dest);
164
+ }
165
+
166
+ @wpc_sunlink($download_dest);
167
+
168
+ // Lets visit the installation once to make the changes in the database
169
+ //$resp = wpc_curl_call($site_url, 0, 5);
170
+ $resp = wp_remote_get($site_url);
171
+
172
+ if(!empty($error)){
173
+ $return['error'] = $error;
174
+ }
175
+ }
176
+ }elseif(wpc_optGET('themes') || wpc_optGET('theme')){
177
+
178
+ $themes = urldecode(wpc_optGET('themes'));
179
+ $arr_themes = explode(',', $themes);
180
+
181
+ $active_theme = array_keys(wpc_get_active_theme());
182
+
183
+ //Do not activate/delete the theme if it is active
184
+ foreach($arr_themes as $tk => $tv){
185
+ if($active_theme[0] == $tv){
186
+ unset($arr_themes[$tk]);
187
+ }
188
+ }
189
+
190
+ if($request == 'activate' && count($arr_themes) == 1){//Activate
191
+
192
+ $res = wpc_activate_theme($arr_themes);
193
+ if(!empty($error)){
194
+ $return['error'] = $error;
195
+ }
196
+ if(!$res){
197
+ $return['error'] = $l['err_activating_theme'];
198
+ }
199
+
200
+ }elseif($request == 'delete'){//Delete
201
+
202
+ $res = wpc_delete_theme($arr_themes);
203
+ if(!empty($error)){
204
+ $return['error'] = $error;
205
+ }
206
+ if(!$res){
207
+ $return['error'] = $l['err_deleting_theme'];
208
+ }
209
+
210
+ }elseif($request == 'install'){//Install Themes
211
+
212
+ $sources = urldecode($_REQUEST['sources']);
213
+ $arr_sources = explode(',', $sources);
214
+
215
+ foreach($arr_themes as $thk => $thval){
216
+
217
+ //Skip if the theme is already installed
218
+ if(wpc_is_theme_installed($thval)){
219
+ continue;
220
+ }
221
+
222
+ $filename = basename(parse_url($arr_sources[$thk], PHP_URL_PATH));
223
+
224
+ $download_dest = $wp_config['uploads_dir'].'/'.$filename;
225
+ $unzip_dest = $wp_config['themes_root_dir'].'/';
226
+
227
+ wpc_get_web_file($arr_sources[$thk], $download_dest);
228
+
229
+ if(wpc_sfile_exists($download_dest)){
230
+ $res = wpc_unzip($download_dest, $unzip_dest);
231
+ }
232
+
233
+ @wpc_sunlink($download_dest);
234
+ }
235
+
236
+ if(!empty($error)){
237
+ $return['error'] = $error;
238
+ }
239
+ }elseif($request == 'update'){//Update Theme
240
+
241
+ $theme_name = urldecode(wpc_optREQ('theme'));
242
+ $download_link = urldecode(wpc_optREQ('source'));
243
+ $site_url = urldecode(wpc_optREQ('siteurl'));
244
+
245
+ $filename = basename(parse_url($download_link, PHP_URL_PATH));
246
+
247
+ $download_dest = $wp_config['uploads_dir'].'/'.$filename;
248
+ $unzip_dest = $wp_config['themes_root_dir'].'/';
249
+
250
+ wpc_get_web_file($download_link, $download_dest);
251
+
252
+ if(wpc_sfile_exists($download_dest)){
253
+ $res = wpc_unzip($download_dest, $unzip_dest);
254
+ }
255
+
256
+ @wpc_sunlink($download_dest);
257
+
258
+ // Lets visit the installation once to make the changes in the database
259
+ //$resp = wpc_curl_call($site_url, 0, 5);
260
+ $resp = wp_remote_get($site_url);
261
+
262
+ if(!empty($error)){
263
+ $return['error'] = $error;
264
+ }
265
+ }
266
+ }
267
+
268
+ if(empty($return['error'])){
269
+ $return['result'] = 'done';
270
+ }
271
+
272
+ //Using serialize here as all_plugins contains class object which are not json_decoded in Softaculous.
273
+ echo json_encode($return);
274
+
275
+ }
file_actions.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (!defined('ABSPATH')){
4
+ exit;
5
+ }
6
+
7
+ function wpc_file_actions(){
8
+ global $error, $l;
9
+
10
+ $return = array();
11
+
12
+ $action = wpc_optREQ('request');
13
+
14
+ if(empty($action)){
15
+ $return['error'] = $l['no_req_post'];
16
+ echo json_encode($return);
17
+ die();
18
+ }
19
+
20
+ if($action == 'put'){
21
+ $filename = urldecode(wpc_optREQ('filename'));
22
+ $putdata = base64_decode(wpc_optREQ('putdata'));
23
+
24
+ $func_response = wpc_put($filename, $putdata);
25
+
26
+ if($func_response){
27
+ $return['done'] = 'done';
28
+ }else{
29
+ $return['error'] = $l['err_exec'];
30
+ }
31
+
32
+ echo json_encode($return);
33
+ die();
34
+ }
35
+
36
+ $args = urldecode(wpc_optREQ('args'));
37
+
38
+ if(function_exists('wpc_'.$action)){
39
+ if(!empty($args)){
40
+ $func_response = call_user_func('wpc_'.$action, $args);
41
+ }else{
42
+ $func_response = call_user_func('wpc_'.$action);
43
+ }
44
+ //$return['func_response'] = $func_response;
45
+
46
+ if($func_response){
47
+ $return['done'] = $l['done'];
48
+ }else{
49
+ $return['error'] = $l['err_exec'];
50
+ }
51
+
52
+ }else{
53
+ $return['error'] = $l['func_not_found'];
54
+ }
55
+
56
+ echo json_encode($return);
57
+
58
+ }
59
+ ?>
get_site_data.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (!defined('ABSPATH')){
4
+ exit;
5
+ }
6
+
7
+ function wpc_get_site_data(){
8
+ global $l, $wp_config, $error;
9
+
10
+ $return = array();
11
+
12
+ $type = wpc_optGET('type');
13
+
14
+ $return['wordpress_current_version'] = wpc_version_wp();
15
+
16
+ if($type == 'plugins'){
17
+ $return['active_plugins'] = wpc_get_option('active_plugins');
18
+ $all_plugins = wpc_get_plugins();
19
+
20
+ foreach($all_plugins as $pk => $pv){
21
+ $installed_version = $pv['Version'];
22
+ }
23
+
24
+ $outdated_plugins = wpc_get_outdated_plugins();
25
+
26
+ $outdated_plugins_keys = array_keys($outdated_plugins);
27
+ foreach($all_plugins as $allk => $allv){
28
+ if(in_array($allk, $outdated_plugins_keys)){
29
+ $all_plugins[$allk]['new_version'] = $outdated_plugins[$allk]->new_version;
30
+ }
31
+ }
32
+
33
+ $return['all_plugins'] = $all_plugins;
34
+
35
+ }elseif($type == 'themes'){
36
+
37
+ $return['active_theme'] = array_keys(wpc_get_active_theme());
38
+ $return['all_themes'] = wpc_get_installed_themes();
39
+
40
+ }else{
41
+ $return['error'] = $l['invalid_params'];
42
+ }
43
+
44
+ echo json_encode($return);
45
+
46
+ }
readme.txt ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === wpcentral ===
2
+ Contributors: softaculous
3
+ Tags: wpcentral, softaculous, sites, manage sites, backup, plugins, themes, manage wordpress,
4
+ Requires at least: 4.4
5
+ Tested up to: 4.9.8
6
+ Requires PHP: 5.3
7
+ Stable tag: 1.0
8
+ License: GPLv2 or later
9
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+
11
+ WPCentral provides a single-login centralized panel where you can manage tons of your WordPress websites efficiently, unitedly as well as singularly.
12
+
13
+ == Description ==
14
+
15
+ If ever you wanted a single panel to manage tons of your Wordpress websites from and save the hassle to login all your website's dashboards separately, you have it here at last. [wpcentral](https://wpcentral.co/ "Manage Multiple WordPress Websites") provides a single panel where you can add infinite number of Wordpress websites for free.
16
+
17
+ Key Features:
18
+
19
+ * Entire data of all your websites can be synced in wpcentral panel so that you may skim through the same without logging in separately. Even if you want to go into detail for any website, you can simply click and you will be logged into the website using the Single Sign On feature.
20
+
21
+ * Should you want to activate/deactivate a plugin/theme on n number of websites, you can achieve this from wpcentral panel using wpcentral plugin. Also, you can install and update the plugins/themes on all the websites in one go.
22
+
23
+ * You can also create Sets of common Plugins and Themes which you want to install on multiple websites together.
24
+
25
+ * If you are worried about loosing your data anytime in the future, we, hereby, resolve all your stress by providing you with the backup feature of your websites. In an unfortunate event, when you loose your website or your website gets corrupted, you can even restore the backup taken previously.
26
+
27
+ * A new WordPress update is out and you are all stressed up to update your websites? No worries, wpcentral helps you achieve the same without the need to go into the dashboard of each website separately.
28
+
29
+ Many more to come! We have a number of other features in our To Do list which we will be adding in the upcoming versions, so stay tuned!
30
+
31
+ Should you have any suggestions to improve wpcentral, want to see some related features in wpcentral to help you in the websites management or if you have any queries, you can open a ticket with us at https://www.softaculous.com/support/open.php.
32
+
33
+ == Installation ==
34
+ 1. Upload the plugin folder to your /wp-content/plugins/ folder
35
+ 2. Activate the plugin through the "Plugins" menu in WordPress.
36
+ 3. You can find the Connection Key by clicking on "View Connection Key" link that appears on the Plugins page.
37
+ 4. Go to [panel.wpcentral.co](https://panel.wpcentral.co/ "Manage Multiple WordPress Websites") and create an account.
38
+ 5. Add your website there by following the steps using the connection key.
39
+ 6. It's Done! You can now start exploring.
verify.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (!defined('ABSPATH')){
4
+ exit;
5
+ }
6
+
7
+ function wpc_verify(){
8
+ global $l, $wpdb, $wp_version, $wp_config, $error;
9
+
10
+ $return = array();
11
+
12
+ $site_settings = array();
13
+ $site_settings['ver'] = $wp_version;
14
+ $site_settings['softpath'] = rtrim(get_home_path(), '/');
15
+ $site_settings['siteurl'] = get_option('siteurl');
16
+ $site_settings['adminurl'] = admin_url();
17
+ $site_settings['softdb'] = $wp_config['softdb'];
18
+ $site_settings['softdbuser'] = $wp_config['softdbuser'];
19
+ $site_settings['softdbhost'] = $wp_config['softdbhost'];
20
+ $site_settings['softdbpass'] = $wp_config['softdbpass'];
21
+ $site_settings['dbprefix'] = $wp_config['dbprefix'];
22
+ $site_settings['site_name'] = get_option('blogname');
23
+
24
+ //Fetch all the table names
25
+ $sql = "SHOW TABLES FROM ".$wp_config['softdb'];
26
+ $results = $wpdb->get_results($sql);
27
+
28
+ $site_settings['softdbtables'] = array();
29
+ foreach($results as $index => $value) {
30
+ foreach($value as $tableName) {
31
+ $site_settings['softdbtables'][] = $tableName;
32
+ }
33
+ }
34
+
35
+ $site_settings['backup_directory'] = $wp_config['plugins_root_dir'].'/wp-central/'.wpc_srandstr(64);
36
+
37
+ $return['data'] = $site_settings;
38
+
39
+ echo json_encode($return);
40
+
41
+ }
wpc_functions.php ADDED
@@ -0,0 +1,2319 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (!defined('ABSPATH')){
4
+ exit;
5
+ }
6
+
7
+ function wpc_died(){
8
+ print_r(error_get_last());
9
+ }
10
+ register_shutdown_function('wpc_died');
11
+
12
+ include_once('wpcentral_lang.php');
13
+
14
+ /*
15
+ * Fetch the value of option name from options table
16
+ *
17
+ * @param string $option_name option_name to retrieve from table.
18
+ * @param mixed $default_value Default value to return when the option does not exist.
19
+ * @param int $site_id Site ID to update. Used for multisite installations only.
20
+ * @param bool $use_cache Whether to use cache or not. Used for multisite installations only.
21
+ * @returns string The option value based on $option_name
22
+ * @since 1.0
23
+ *
24
+ * @refer get_option()
25
+ * @link https://developer.wordpress.org/reference/functions/get_option/
26
+ */
27
+ function wpc_get_option($option_name, $default_value = false, $site_id = null, $use_cache = true){
28
+
29
+ if($site_id !== null && is_multisite()){
30
+ return get_site_option($option_name, $default_value, $use_cache);
31
+ }
32
+ return get_option($option_name, $default_value);
33
+ }
34
+
35
+ /*
36
+ * Generate a random string for the given length
37
+ *
38
+ * @param int $length The number of charactes that should be returned
39
+ * @return string Randomly geterated string of the given number of charaters
40
+ * @since 1.0
41
+ */
42
+ function wpc_srandstr($length){
43
+ $randstr = "";
44
+ for($i = 0; $i < $length; $i++){
45
+ $randnum = mt_rand(0,61);
46
+ if($randnum < 10){
47
+ $randstr .= chr($randnum+48);
48
+ }elseif($randnum < 36){
49
+ $randstr .= chr($randnum+55);
50
+ }else{
51
+ $randstr .= chr($randnum+61);
52
+ }
53
+ }
54
+ return strtolower($randstr);
55
+ }
56
+
57
+ /*
58
+ * A function to display preformatted array. Basically adds the <pre> before and after the print_r() output.
59
+ *
60
+ * @param array $array
61
+ * @return string Best for HTML dump of an array.
62
+ * @since 1.0
63
+ */
64
+ function wpc_print($array){
65
+ echo '<pre>';
66
+ print_r($array);
67
+ echo '</pre>';
68
+ }
69
+
70
+ /**
71
+ * A function to return all the installed plugins and their description.
72
+ *
73
+ * @since 1.0
74
+ */
75
+ function wpc_get_plugins(){
76
+ return get_plugins();
77
+ }
78
+
79
+ /**
80
+ * A function to check if the plugin is active or not.
81
+ *
82
+ * @param string $pluginBasename slug of the plugin
83
+ * @since 1.0
84
+ */
85
+ function wpc_is_plugin_active($pluginBasename){
86
+ return is_plugin_active($pluginBasename);
87
+ }
88
+
89
+ /**
90
+ * A function to check if the plugin is installed.
91
+ *
92
+ * @param string $plslug slug of the plugin
93
+ * @since 1.0
94
+ */
95
+ function wpc_is_plugin_installed($plslug){
96
+
97
+ $all_installed_plugins = wpc_get_plugins();
98
+ $slugs = array_keys($all_installed_plugins);
99
+
100
+ $is_installed = 0;
101
+ foreach($all_installed_plugins as $key => $val){
102
+ if(strpos($key, $plslug) !== false){
103
+ $is_installed = true;
104
+ break;
105
+ }
106
+ }
107
+
108
+ return $is_installed;
109
+ }
110
+
111
+ /**
112
+ * Activates the plugins on the website
113
+ *
114
+ * @param array $plugin_slug array of plugin's slug values
115
+ * @since 1.0
116
+ */
117
+ function wpc_activate_plugin($plugin_slug = array()){
118
+ global $wp_config;
119
+
120
+ $active_plugins = wpc_get_option('active_plugins');
121
+
122
+ // Build final list of selected plugins and activated ones.
123
+ foreach($plugin_slug as $k => $v){
124
+ if(in_array($v, $active_plugins)){
125
+ continue;
126
+ }
127
+
128
+ $active_plugins[] = $v;
129
+ }
130
+
131
+ $res = update_option('active_plugins', $active_plugins);
132
+
133
+ return $res;
134
+ }
135
+
136
+ /**
137
+ * De-activates the plugins on the website
138
+ *
139
+ * @param array $plugin_slug array of plugin's slug values
140
+ * @since 1.0
141
+ */
142
+ function wpc_deactivate_plugin($plugin_slug = array()){
143
+ global $wp_config;
144
+
145
+ $active_plugins = wpc_get_option('active_plugins');
146
+
147
+ // Build final list of selected plugins and activated ones.
148
+ foreach($plugin_slug as $k => $v){
149
+
150
+ if(in_array($v, $active_plugins)){
151
+ continue;
152
+ }
153
+
154
+ $active_plugins[] = $v;
155
+ }
156
+
157
+ foreach($active_plugins as $pk => $pv){
158
+ if(in_array($pv, $plugin_slug)){
159
+ unset($active_plugins[$pk]);
160
+ }
161
+ }
162
+
163
+ $res = update_option('active_plugins', $active_plugins);
164
+
165
+ return $res;
166
+ }
167
+
168
+ /**
169
+ * Fetch the list of outdated plugins on the website
170
+ *
171
+ * @since 1.0
172
+ */
173
+ function wpc_get_outdated_plugins(){
174
+ global $wp_config, $error;
175
+
176
+ // Get the list of active plugins
177
+ $squery = 'SELECT `option_value` FROM `'.$wp_config['dbprefix'].'options` WHERE `option_name` = "active_plugins";';
178
+ $sresult = wpc_sdb_query($squery, $wp_config['softdbhost'], $wp_config['softdbuser'], $wp_config['softdbpass'], $wp_config['softdb']);
179
+
180
+ $active = array();
181
+ $active = unserialize($sresult[0]['option_value']);
182
+
183
+ foreach($active as $plugin_file){
184
+ $plugin_data = array();
185
+ if (!wpc_sfile_exists($wp_config['plugins_root_dir'].'/'.$plugin_file)){
186
+ continue;
187
+ }
188
+
189
+ $plugin_data = wpc_get_plugin_data($wp_config['plugins_root_dir'].'/'.$plugin_file);
190
+
191
+ if(empty($plugin_data['Plugin Name'])){
192
+ continue;
193
+ }else{
194
+ $plugin_data['Name'] = $plugin_data['Plugin Name'];
195
+ }
196
+
197
+ $plugins[$plugin_file] = $plugin_data;
198
+ }
199
+
200
+ uasort($plugins, '_sort_uname_callback');
201
+
202
+ $to_send = (object) compact('plugins', 'active');
203
+ $options = array('plugins' => serialize($to_send));
204
+
205
+ // Check the WordPress API to get the list of outdated plugins
206
+ //$raw_response = wpc_curl_call('http://api.wordpress.org/plugins/update-check/1.0/', 0, 5, $options);
207
+ $raw_response = wp_remote_post('http://api.wordpress.org/plugins/update-check/1.0/', array('body' => $options));
208
+ $body = wp_remote_retrieve_body($raw_response);
209
+ $outdated_plugins = unserialize($body);
210
+
211
+ // We need the Plugin name to send via email
212
+ foreach($outdated_plugins as $plugin_file => $p_data){
213
+ if(!empty($plugins[$plugin_file]['Name'])){
214
+ $outdated_plugins[$plugin_file]->Name = $plugins[$plugin_file]['Name'];
215
+ }
216
+ }
217
+
218
+ return $outdated_plugins;
219
+ }
220
+
221
+ /**
222
+ * This is to extract the plugin details from the plugin file
223
+ *
224
+ * @param string $pluginPath directory path of the installed plugin
225
+ * @since 1.0
226
+ */
227
+ function wpc_get_plugin_data($pluginPath = ''){
228
+ global $plugin_details;
229
+
230
+ $plugin_details = array();
231
+
232
+ if(empty($pluginPath)){
233
+ return false;
234
+ }
235
+
236
+ $tmp_data = array();
237
+ $data = array();
238
+ $data = wpc_sfile($pluginPath);
239
+ preg_replace_callback('/\n(\s*?)(\*?)(\s*?)Plugin(\s*?)Name:(.*?)\n/is', 'wpc_plugin_callback', $data, 1);
240
+ preg_replace_callback('/\n(\s*?)(\*?)(\s*?)Plugin(\s*?)URI:(.*?)\n/is', 'wpc_plugin_callback', $data, 1);
241
+ preg_replace_callback('/\n(\s*?)(\*?)(\s*?)Description:(.*?)\n/is', 'wpc_plugin_callback', $data, 1);
242
+ preg_replace_callback('/\n(\s*?)(\*?)(\s*?)Version:(.*?)\n/is', 'wpc_plugin_callback', $data, 1);
243
+
244
+ return $plugin_details;
245
+ }
246
+
247
+ // This is a callback function for preg_replace in wpc_get_plugin_data
248
+ function wpc_plugin_callback($matches){
249
+ global $plugin_details;
250
+ $tmp_data = explode(':', $matches[0], 2);
251
+ $tmp_data[0] = str_replace('*', '', $tmp_data[0]);
252
+ $key = trim($tmp_data[0]);
253
+ $value = trim($tmp_data[1]);
254
+ $plugin_details[$key] = $value;
255
+ }
256
+
257
+ /**
258
+ * A function to check if the theme is installed.
259
+ *
260
+ * @param string $thslug slug of the theme
261
+ * @since 1.0
262
+ */
263
+ function wpc_is_theme_installed($thslug){
264
+
265
+ $all_installed_themes = wp_get_themes();
266
+ $slugs = array_keys($all_installed_themes);
267
+
268
+ if(isset($all_installed_themes[$thslug])){
269
+ return true;
270
+ }
271
+
272
+ return false;
273
+ }
274
+
275
+ /**
276
+ * Returns active theme for the website.
277
+ *
278
+ * @since 1.0
279
+ */
280
+ function wpc_get_active_theme(){
281
+ $raw_list = wp_get_theme();
282
+ return wpc_get_themes_details(array($raw_list->stylesheet));
283
+ }
284
+
285
+ /**
286
+ * A function to return all the installed themes and their description.
287
+ *
288
+ * @since 1.0
289
+ */
290
+ function wpc_get_installed_themes(){
291
+ $raw_list = wp_get_themes();
292
+ $theme_slugs = array_keys($raw_list);
293
+
294
+ return wpc_get_themes_details($theme_slugs);
295
+ }
296
+
297
+ /**
298
+ * Returns details of the themes from wordPress.org.
299
+ *
300
+ * @param array $themes array of themes
301
+ * @since 1.0
302
+ */
303
+ function wpc_get_themes_details($themes = array()){
304
+ global $wp_config, $error;
305
+
306
+ $apiurl ='http://api.wordpress.org/themes/info/1.0/';
307
+ $theme_details = array();
308
+ foreach($themes as $current_theme){
309
+ $theme_data = wpc_get_theme_data($wp_config['themes_root_dir'].'/'.$current_theme.'/style.css');
310
+
311
+ $post_data = array(
312
+ 'action' => 'theme_information',
313
+ 'request' => serialize( (object) array( 'slug' => $current_theme )));
314
+
315
+ //$api_data = wpc_curl_call($apiurl, 0, 5, $post_data);
316
+ //$api_data = unserialize($api_data);
317
+
318
+ $raw_response = wp_remote_post($apiurl, array('body' => $post_data));
319
+ $body = wp_remote_retrieve_body($raw_response);
320
+ $api_data = unserialize($body);
321
+
322
+ $theme_details[$current_theme] = $api_data;
323
+ $theme_details[$current_theme]->installed_version = $theme_data['Version'];
324
+
325
+ if(wpc_sversion_compare($theme_data['Version'], $api_data->version, '<')){
326
+ $theme_details[$current_theme]->new_version = $api_data->version;
327
+ }
328
+ }
329
+ return $theme_details;
330
+ }
331
+
332
+ /**
333
+ * This is to extract the theme details from the theme file
334
+ *
335
+ * @param string $themePath directory path of the installed theme
336
+ * @since 1.0
337
+ */
338
+ function wpc_get_theme_data($themePath = ''){
339
+
340
+ global $theme_details;
341
+
342
+ $theme_details = array();
343
+
344
+ if(empty($themePath)){
345
+ return false;
346
+ }
347
+
348
+ $tmp_data = array();
349
+ $data = array();
350
+ $data = wpc_sfile($themePath);
351
+ preg_replace_callback('/\n(\s*?)(\*?)(\s*?)Theme(\s*?)Name:(.*?)\n/is', 'wpc_theme_callback', $data, 1);
352
+ preg_replace_callback('/\n(\s*?)(\*?)(\s*?)Theme(\s*?)URI:(.*?)\n/is', 'wpc_theme_callback', $data, 1);
353
+ preg_replace_callback('/\n(\s*?)(\*?)(\s*?)Description:(.*?)\n/is', 'wpc_theme_callback', $data, 1);
354
+ preg_replace_callback('/\n(\s*?)(\*?)(\s*?)Version:(.*?)\n/is', 'wpc_theme_callback', $data, 1);
355
+ preg_replace_callback('/\n(\s*?)(\*?)(\s*?)Author:(.*?)\n/is', 'wpc_theme_callback', $data, 1);
356
+ preg_replace_callback('/\n(\s*?)(\*?)(\s*?)Author(\s*?)URI:(.*?)\n/is', 'wpc_theme_callback', $data, 1);
357
+
358
+ return $theme_details;
359
+ }
360
+
361
+ // This is a callback function for preg_replace used in wpc_get_theme_data
362
+ function wpc_theme_callback($matches){
363
+ global $theme_details;
364
+ $tmp_data = explode(':', $matches[0], 2);
365
+ $tmp_data[0] = str_replace('*', '', $tmp_data[0]);
366
+ $key = trim($tmp_data[0]);
367
+ $value = trim($tmp_data[1]);
368
+ $theme_details[$key] = $value;
369
+ }
370
+
371
+ /**
372
+ * Activates the theme on the website
373
+ *
374
+ * @param string $theme_slug slug of the theme
375
+ * @since 1.0
376
+ */
377
+ function wpc_activate_theme($theme_slug = array()){
378
+ global $error, $l;
379
+
380
+ $theme_root = $wp_config['themes_root_dir'].'/'.$theme_slug[0];
381
+
382
+ $res = switch_theme($theme_root, $theme_slug[0]);
383
+
384
+ if(is_wp_error($res)) {
385
+ $error = $res->get_error_message();
386
+ }elseif($res === false) {
387
+ $error = $l['action_failed'];
388
+ }
389
+
390
+ if(!empty($error)){
391
+ return false;
392
+ }
393
+
394
+ return true;
395
+ }
396
+
397
+ /**
398
+ * Function to delete a theme
399
+ *
400
+ * @param string $theme_slug slug of the theme
401
+ * @since 1.0
402
+ */
403
+ function wpc_delete_theme($theme_slug = array()){
404
+ global $error, $l;
405
+
406
+ foreach($theme_slug as $slug){
407
+ $res = delete_theme($slug);
408
+ }
409
+
410
+ if(is_wp_error($res)) {
411
+ $error = $res->get_error_message();
412
+
413
+ }elseif($res === false) {
414
+ $error = $l['action_failed'];
415
+ }
416
+
417
+ if(!empty($error)){
418
+ return false;
419
+ }
420
+
421
+ return true;
422
+ }
423
+
424
+ /**
425
+ * Takes care of Slashes
426
+ *
427
+ * @param string $string The string that will be processed
428
+ * @return string A string that is safe to use for Database Queries, etc
429
+ * @since 1.0
430
+ */
431
+ function wpc_inputsec($string){
432
+
433
+ if(!get_magic_quotes_gpc()){
434
+
435
+ $string = addslashes($string);
436
+
437
+ }else{
438
+
439
+ $string = stripslashes($string);
440
+ $string = addslashes($string);
441
+
442
+ }
443
+
444
+ // This is to replace ` which can cause the command to be executed in exec()
445
+ $string = str_replace('`', '\`', $string);
446
+
447
+ return $string;
448
+
449
+ }
450
+
451
+ /**
452
+ * Converts Special characters to html entities
453
+ *
454
+ * @param string $string The string containing special characters
455
+ * @return string A string containing special characters replaced by html entities of the format &#ASCIICODE;
456
+ * @since 1.0
457
+ */
458
+ function wpc_htmlizer($string){
459
+
460
+ global $globals;
461
+
462
+ $string = htmlentities($string, ENT_QUOTES, 'UTF-8');
463
+
464
+ preg_match_all('/(&amp;#(\d{1,7}|x[0-9a-fA-F]{1,6});)/', $string, $matches);
465
+
466
+ foreach($matches[1] as $mk => $mv){
467
+ $tmp_m = wpc_entity_check($matches[2][$mk]);
468
+ $string = str_replace($matches[1][$mk], $tmp_m, $string);
469
+ }
470
+
471
+ return $string;
472
+
473
+ }
474
+
475
+ /**
476
+ * Used in function htmlizer()
477
+ *
478
+ * @param string $string
479
+ * @return string
480
+ * @since 1.0
481
+ */
482
+ function wpc_entity_check($string){
483
+
484
+ //Convert Hexadecimal to Decimal
485
+ $num = ((substr($string, 0, 1) === 'x') ? hexdec(substr($string, 1)) : (int) $string);
486
+
487
+ //Squares and Spaces - return nothing
488
+ $string = (($num > 0x10FFFF || ($num >= 0xD800 && $num <= 0xDFFF) || $num < 0x20) ? '' : '&#'.$num.';');
489
+
490
+ return $string;
491
+
492
+ }
493
+
494
+ /**
495
+ * OPTIONAL REQUEST of the given REQUEST Key
496
+ *
497
+ * @param string $name The key of the $_REQUEST array i.e. the name of the input / textarea text
498
+ * @param string $default The value to return if the $_REQUEST[$name] is NOT SET
499
+ * @return string Returns the string if the REQUEST is there otherwise the default value given.
500
+ * @since 1.0
501
+ */
502
+ function wpc_optREQ($name, $default = ''){
503
+
504
+ global $error;
505
+
506
+ //Check the POSTED NAME was posted
507
+ if(isset($_REQUEST[$name])){
508
+
509
+ return wpc_inputsec(wpc_htmlizer(trim($_REQUEST[$name])));
510
+
511
+ }else{
512
+
513
+ return $default;
514
+
515
+ }
516
+
517
+ }
518
+
519
+ /**
520
+ * OPTIONAL GET of the given GET Key i.e. dont throw a error if not there
521
+ *
522
+ * @param string $name The key of the $_GET array i.e. the name of the input / textarea text
523
+ * @param string $default The value to return if the $_GET[$name] is NOT SET
524
+ * @return string Returns the string if the GET is there otherwise the default value given.
525
+ * @since 1.0
526
+ */
527
+ function wpc_optGET($name, $default = ''){
528
+
529
+ global $error;
530
+
531
+ //Check the GETED NAME was GETed
532
+ if(isset($_GET[$name])){
533
+
534
+ return wpc_inputsec(wpc_htmlizer(trim($_GET[$name])));
535
+
536
+ }else{
537
+
538
+ return $default;
539
+
540
+ }
541
+
542
+ }
543
+
544
+ /**
545
+ * A function to load a file from the net
546
+ *
547
+ * @param string $url The URL to read
548
+ * @param string $writefilename Instead of returning the data save it to the path given
549
+ * @return string The data fetched
550
+ * @since 1.0
551
+ */
552
+ function wpc_get_web_file($url, $writefilename = ''){
553
+
554
+ // Set the curl parameters.
555
+ $ch = curl_init();
556
+ curl_setopt($ch, CURLOPT_URL, $url);
557
+
558
+ // Turn off the server and peer verification (TrustManager Concept).
559
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
560
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
561
+
562
+ // Follow redirects
563
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
564
+
565
+ // UserAgent and Cookies
566
+ curl_setopt($ch, CURLOPT_USERAGENT, 'wpcentral');
567
+
568
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
569
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120); // Max time to connect
570
+
571
+ curl_setopt($ch, CURLOPT_TIMEOUT, 5);
572
+
573
+ // Get response from the server.
574
+ $file = curl_exec($ch);
575
+
576
+ $meta = curl_getinfo($ch);
577
+
578
+ curl_close($ch);
579
+
580
+ //Are we to store the file
581
+ if(empty($writefilename)){
582
+ return $file;
583
+
584
+ //Store the file
585
+ }else{
586
+ $fp = @fopen($writefilename, "wb"); //This opens the file
587
+
588
+ //If its opened then proceed
589
+ if($fp){
590
+ if(@fwrite($fp, $file) === FALSE){
591
+ return false;
592
+ //Wrote the file
593
+ }else{
594
+ @fclose($fp);
595
+ return true;
596
+ }
597
+ }
598
+ }
599
+ return false;
600
+ }
601
+
602
+ /**
603
+ * A Function to unzip a ZIP file
604
+ *
605
+ * @param string $file The ZIP File
606
+ * @param string $destination The Final destination where the file will be unzipped
607
+ * @param int $overwrite Whether to Overwrite existing files
608
+ * @param array $include include files of the given pattern
609
+ * @param array $exclude exclude files of the given pattern
610
+ * @return boolean
611
+ * @since 1.0
612
+ */
613
+ function wpc_unzip($file, $destination, $overwrite = 0){
614
+
615
+ include_once('wpc_soft_pclzip.php');
616
+ $archive = new softpclzip($file);
617
+
618
+ $result = $archive->_extract(PCLZIP_OPT_PATH, $destination,
619
+ PCLZIP_CB_PRE_EXTRACT, 'wpc_inc_exc',
620
+ PCLZIP_OPT_REPLACE_NEWER);
621
+
622
+ if($result == 0){
623
+ return false;
624
+ }
625
+ return true;
626
+ }
627
+
628
+ /**
629
+ * Process includes and excludes of function unzip
630
+ *
631
+ * @param $p_event
632
+ * @param $v
633
+ * @return Returns boolean
634
+ * @since 1.0
635
+ */
636
+ function wpc_inc_exc($p_event, &$v){
637
+ return 1;
638
+ }
639
+
640
+ /**
641
+ * Checks if a file is symlink or hardlink
642
+ *
643
+ * @returns bool false if file is a symlink or a hardlink else true
644
+ * @since 1.0
645
+ */
646
+ function wpc_is_safe_file($path){
647
+
648
+ // Is it a symlink ?
649
+ if(is_link($path)) return false;
650
+
651
+ // Is it a file and is a link ?
652
+ $stat = @stat($path);
653
+ if(!is_dir($path) && $stat['nlink'] > 1) return false;
654
+
655
+ return true;
656
+ }
657
+
658
+ /**
659
+ * Read file contents from the DESTINATION. Should be used when an installations file is to be fetched.
660
+ * For local package file, use the PHP file() function. The main usage of sfile is for import or upgrade !
661
+ *
662
+ * @package files
663
+ * @param string $path The path of the file
664
+ * @returns bool
665
+ * @since 1.0
666
+ */
667
+ function wpc_sfile($path){
668
+
669
+ // Is it safe to read this file ?
670
+ if(!wpc_is_safe_file($path)){
671
+ return false;
672
+ }
673
+
674
+ return @implode('', file($path));
675
+ }
676
+
677
+ /**
678
+ * Fetch website's configuration details from the config file
679
+ *
680
+ * @since 1.0
681
+ */
682
+ function wpc_fetch_wp_config(){
683
+
684
+ global $wpdb;
685
+
686
+ $r = array();
687
+
688
+ $r['softdbhost'] = $wpdb->dbhost;
689
+ $r['softdbuser'] = $wpdb->dbuser;
690
+ $r['softdbpass'] = $wpdb->dbpassword;
691
+ $r['softdb'] = $wpdb->dbname;
692
+ $r['dbprefix'] = $wpdb->prefix;
693
+
694
+ $r['ver'] = wpc_version_wp();
695
+
696
+ //No trailing slash
697
+ $updir = wp_upload_dir();
698
+ $r['uploads_dir'] = realpath($updir['basedir']);
699
+ $r['themes_root_dir'] = realpath(get_theme_root());
700
+ $r['plugins_root_dir'] = realpath(plugin_dir_path( __DIR__ ));
701
+
702
+ return $r;
703
+ }
704
+
705
+ /**
706
+ * Fetch website's currently installed version
707
+ *
708
+ * @since 1.0
709
+ */
710
+ function wpc_version_wp(){
711
+
712
+ $file = wpc_sfile(get_home_path().'wp-includes/version.php');
713
+
714
+ if(!empty($file)){
715
+ wpc_soft_preg_replace('/\$wp_version(\s*?)=(\s*?)("|\')(.*?)("|\');/is', $file, $ver, 4);
716
+ }
717
+
718
+ return $ver;
719
+ }
720
+
721
+ /**
722
+ * This function will preg_match the pattern and return the respective values in $var
723
+ *
724
+ * @param $pattern This should be the pattern to be matched
725
+ * @param $file This should have the data to search from
726
+ * @param $var This will be the variable which will have the preg matched data
727
+ * @param $valuenum This should be the no of regular expression to be returned in $var
728
+ * @param $stripslashes 0 or 1 depending upon whether the stripslashes function is to be applied (1) or not (0)
729
+ * @return string Will pass value by reference in $var
730
+ * @since 1.0
731
+ */
732
+ function wpc_soft_preg_replace($pattern, $file, &$var, $valuenum){
733
+ preg_match($pattern, $file, $matches);
734
+ $var = trim($matches[$valuenum]);
735
+ }
736
+
737
+ /**
738
+ * Unserialize a string and also fixes any broken serialized string before unserializing
739
+ *
740
+ * @param string $str
741
+ * @return array Returns an array if successful otherwise false
742
+ * @since 1.0
743
+ */
744
+ function wpc_unserialize($str){
745
+
746
+ $var = @unserialize($str);
747
+
748
+ if(empty($var)){
749
+
750
+ preg_match_all('!s:(\d+):"(.*?)";!s', $str, $matches);
751
+ foreach($matches[2] as $mk => $mv){
752
+ $tmp_str = 's:'.strlen($mv).':"'.$mv.'";';
753
+ $str = str_replace($matches[0][$mk], $tmp_str, $str);
754
+ }
755
+ $var = @unserialize($str);
756
+ }
757
+
758
+ //If it is still empty false
759
+ if($var === false){
760
+ return false;
761
+ }else{
762
+ return $var;
763
+ }
764
+
765
+ }
766
+
767
+ ////////////////////////////////////////////
768
+ // Custom MySQL functions for WPCentral
769
+ ///////////////////////////////////////////
770
+
771
+ /**
772
+ * Connect to mysqli if exists else mysql
773
+ *
774
+ * @param string $host database host to be connected
775
+ * @param string $user db username to be used to connect
776
+ * @param string $pass db password to be used to connect
777
+ * @param string $newlink create a new link (mysql only)
778
+ * @returns string $conn returns resource link on success or FALSE on failure
779
+ * @since 1.0
780
+ */
781
+ function wpc_mysql_connect($host, $user, $pass, $newlink = false){
782
+
783
+ if(extension_loaded('mysqli')){
784
+ //echo 'mysqli';
785
+ //To handle connection if user passes a custom port along with the host as 127.0.0.1:6446.
786
+ //For testing, use port 127.0.0.1 instead of localhost as 127.0.0.1:6446 http://php.net/manual/en/mysqli.construct.php#112328
787
+ $exh = explode(':', $host);
788
+ if(!empty($exh[1])){
789
+ $sconn = @mysqli_connect($exh[0], $user, $pass, '', $exh[1]);
790
+ }else{
791
+ $sconn = @mysqli_connect($host, $user, $pass);
792
+ }
793
+ }else{
794
+ //echo 'mysql';
795
+ $sconn = @mysql_connect($host, $user, $pass, $newlink);
796
+ }
797
+
798
+ return $sconn;
799
+ }
800
+
801
+ /**
802
+ * Set the database character set
803
+ *
804
+ * @param string $conn database connection string
805
+ * @param string $charset character set to convert to
806
+ * @returns bool true if character set is set
807
+ * @since 1.0
808
+ */
809
+ function wpc_mysql_set_charset($conn, $charset){
810
+
811
+ if(extension_loaded('mysqli')){
812
+ //echo 'mysqli';
813
+ $return = @mysqli_set_charset($conn, $charset);
814
+ }else{
815
+ //echo 'mysql';
816
+ $return = @mysql_set_charset($charset, $conn);
817
+ }
818
+
819
+ return $return;
820
+ }
821
+
822
+ /**
823
+ * Selects database mysqli if exists else mysql
824
+ *
825
+ * @param string $db database to be selected
826
+ * @param string $conn Resource Link
827
+ * @returns bool TRUE on success or FALSE on failure
828
+ * @since 1.0
829
+ */
830
+ function wpc_mysql_select_db($db, $conn){
831
+
832
+ if(extension_loaded('mysqli')){
833
+ $return = @mysqli_select_db($conn, $db);
834
+ }else{
835
+ $return = @mysql_select_db($db, $conn);
836
+ }
837
+
838
+ return $return;
839
+ }
840
+
841
+ /**
842
+ * Executes the query mysqli if exists else mysql
843
+ *
844
+ * @param string $db database to be selected
845
+ * @param string $conn Resource Link
846
+ * @returns bool TRUE on success or FALSE on failure
847
+ * @since 1.0
848
+ */
849
+ function wpc_mysql_query($query, $conn){
850
+
851
+ if(extension_loaded('mysqli')){
852
+ $return = @mysqli_query($conn, $query);
853
+ }else{
854
+ $return = @mysql_query($query, $conn);
855
+ }
856
+
857
+ return $return;
858
+ }
859
+
860
+ /**
861
+ * Fetches the result from a result link mysqli if exists else mysql
862
+ *
863
+ * @param string $result result to fetch the data from
864
+ * @returns mixed Returns an array of strings that corresponds to the fetched row, or FALSE if there are no more rows
865
+ * @since 1.0
866
+ */
867
+ function wpc_mysql_fetch_array($result){
868
+
869
+ if(extension_loaded('mysqli')){
870
+ $return = @mysqli_fetch_array($result);
871
+ }else{
872
+ $return = @mysql_fetch_array($result);
873
+ }
874
+
875
+ return $return;
876
+ }
877
+
878
+ /**
879
+ * Fetches the result into associative array from a result link mysqli if exists else mysql
880
+ *
881
+ * @param string $result result to fetch the data from
882
+ * @returns mixed Returns an associative array of strings that corresponds to the fetched row, or FALSE if there are no more rows
883
+ * @since 1.0
884
+ */
885
+ function wpc_mysql_fetch_assoc($result){
886
+
887
+ if(extension_loaded('mysqli')){
888
+ $return = @mysqli_fetch_assoc($result);
889
+ }else{
890
+ $return = @mysql_fetch_assoc($result);
891
+ }
892
+
893
+ return $return;
894
+ }
895
+
896
+ /**
897
+ * Get a result row as an enumerated array mysqli if exists else mysql
898
+ *
899
+ * @param string $result result to fetch the data from
900
+ * @returns mixed returns an array of strings that corresponds to the fetched row or FALSE if there are no more rows
901
+ * @since 1.0
902
+ */
903
+ function wpc_mysql_fetch_row($result){
904
+
905
+ if(extension_loaded('mysqli')){
906
+ $return = @mysqli_fetch_row($result);
907
+ }else{
908
+ $return = @mysql_fetch_row($result);
909
+ }
910
+
911
+ return $return;
912
+ }
913
+
914
+ /**
915
+ * Get column information from a result and return as an object
916
+ *
917
+ * @param string $result result to fetch the data from
918
+ * @param string $field The numerical field offset
919
+ * @returns object Returns the definition of one column of a result set as an object.
920
+ * @since 1.0
921
+ */
922
+ function wpc_mysql_fetch_field($result, $field){
923
+
924
+ if(extension_loaded('mysqli')){
925
+ $return = @mysqli_fetch_field_direct($result, $field);
926
+ }else{
927
+ $return = @mysql_fetch_field($result, $field);
928
+ }
929
+
930
+ return $return;
931
+ }
932
+
933
+ /**
934
+ * Gets the fields meta
935
+ *
936
+ * @param string $result result to fetch the data from
937
+ * @returns object returns object of fields meta
938
+ * @since 1.0
939
+ */
940
+ function wpc_getFieldsMeta($result){
941
+ // Build an associative array for a type look up
942
+
943
+ if(!defined('WPC_MYSQLI_TYPE_VARCHAR')){
944
+ define('WPC_MYSQLI_TYPE_VARCHAR', 15);
945
+ }
946
+
947
+ $typeAr = array();
948
+ $typeAr[MYSQLI_TYPE_DECIMAL] = 'real';
949
+ $typeAr[MYSQLI_TYPE_NEWDECIMAL] = 'real';
950
+ $typeAr[MYSQLI_TYPE_BIT] = 'int';
951
+ $typeAr[MYSQLI_TYPE_TINY] = 'int';
952
+ $typeAr[MYSQLI_TYPE_SHORT] = 'int';
953
+ $typeAr[MYSQLI_TYPE_LONG] = 'int';
954
+ $typeAr[MYSQLI_TYPE_FLOAT] = 'real';
955
+ $typeAr[MYSQLI_TYPE_DOUBLE] = 'real';
956
+ $typeAr[MYSQLI_TYPE_NULL] = 'null';
957
+ $typeAr[MYSQLI_TYPE_TIMESTAMP] = 'timestamp';
958
+ $typeAr[MYSQLI_TYPE_LONGLONG] = 'int';
959
+ $typeAr[MYSQLI_TYPE_INT24] = 'int';
960
+ $typeAr[MYSQLI_TYPE_DATE] = 'date';
961
+ $typeAr[MYSQLI_TYPE_TIME] = 'time';
962
+ $typeAr[MYSQLI_TYPE_DATETIME] = 'datetime';
963
+ $typeAr[MYSQLI_TYPE_YEAR] = 'year';
964
+ $typeAr[MYSQLI_TYPE_NEWDATE] = 'date';
965
+ $typeAr[MYSQLI_TYPE_ENUM] = 'unknown';
966
+ $typeAr[MYSQLI_TYPE_SET] = 'unknown';
967
+ $typeAr[MYSQLI_TYPE_TINY_BLOB] = 'blob';
968
+ $typeAr[MYSQLI_TYPE_MEDIUM_BLOB] = 'blob';
969
+ $typeAr[MYSQLI_TYPE_LONG_BLOB] = 'blob';
970
+ $typeAr[MYSQLI_TYPE_BLOB] = 'blob';
971
+ $typeAr[MYSQLI_TYPE_VAR_STRING] = 'string';
972
+ $typeAr[MYSQLI_TYPE_STRING] = 'string';
973
+ $typeAr[WPC_MYSQLI_TYPE_VARCHAR] = 'string'; // for Drizzle
974
+ // MySQL returns MYSQLI_TYPE_STRING for CHAR
975
+ // and MYSQLI_TYPE_CHAR === MYSQLI_TYPE_TINY
976
+ // so this would override TINYINT and mark all TINYINT as string
977
+ // https://sourceforge.net/p/phpmyadmin/bugs/2205/
978
+ //$typeAr[MYSQLI_TYPE_CHAR] = 'string';
979
+ $typeAr[MYSQLI_TYPE_GEOMETRY] = 'geometry';
980
+ $typeAr[MYSQLI_TYPE_BIT] = 'bit';
981
+
982
+ $fields = mysqli_fetch_fields($result);
983
+
984
+ // this happens sometimes (seen under MySQL 4.0.25)
985
+ if (!is_array($fields)) {
986
+ return false;
987
+ }
988
+
989
+ foreach ($fields as $k => $field) {
990
+ $fields[$k]->_type = $field->type;
991
+ $fields[$k]->type = $typeAr[$field->type];
992
+ $fields[$k]->_flags = $field->flags;
993
+ $fields[$k]->flags = wpc_mysql_field_flags($result, $k);
994
+
995
+ // Enhance the field objects for mysql-extension compatibilty
996
+ //$flags = explode(' ', $fields[$k]->flags);
997
+ //array_unshift($flags, 'dummy');
998
+ $fields[$k]->multiple_key
999
+ = (int) (bool) ($fields[$k]->_flags & MYSQLI_MULTIPLE_KEY_FLAG);
1000
+ $fields[$k]->primary_key
1001
+ = (int) (bool) ($fields[$k]->_flags & MYSQLI_PRI_KEY_FLAG);
1002
+ $fields[$k]->unique_key
1003
+ = (int) (bool) ($fields[$k]->_flags & MYSQLI_UNIQUE_KEY_FLAG);
1004
+ $fields[$k]->not_null
1005
+ = (int) (bool) ($fields[$k]->_flags & MYSQLI_NOT_NULL_FLAG);
1006
+ $fields[$k]->unsigned
1007
+ = (int) (bool) ($fields[$k]->_flags & MYSQLI_UNSIGNED_FLAG);
1008
+ $fields[$k]->zerofill
1009
+ = (int) (bool) ($fields[$k]->_flags & MYSQLI_ZEROFILL_FLAG);
1010
+ $fields[$k]->numeric
1011
+ = (int) (bool) ($fields[$k]->_flags & MYSQLI_NUM_FLAG);
1012
+ $fields[$k]->blob
1013
+ = (int) (bool) ($fields[$k]->_flags & MYSQLI_BLOB_FLAG);
1014
+ }
1015
+ return $fields;
1016
+ }
1017
+
1018
+ /**
1019
+ * Returns the field flags of the field in text format
1020
+ *
1021
+ * @param string $result result to fetch the data from
1022
+ * @param string $field The numerical field offset
1023
+ * @returns string Returns the field flags of the field in text format
1024
+ * @since 1.0
1025
+ */
1026
+ function wpc_mysql_field_flags($result, $i){
1027
+
1028
+ if(!extension_loaded('mysqli')){
1029
+ return mysql_field_flags($result, $i);
1030
+ }
1031
+
1032
+ $f = mysqli_fetch_field_direct($result, $i);
1033
+ $type = $f->type;
1034
+ $charsetnr = $f->charsetnr;
1035
+ $f = $f->flags;
1036
+ $flags = '';
1037
+ if ($f & MYSQLI_UNIQUE_KEY_FLAG) {
1038
+ $flags .= 'unique ';
1039
+ }
1040
+ if ($f & MYSQLI_NUM_FLAG) {
1041
+ $flags .= 'num ';
1042
+ }
1043
+ if ($f & MYSQLI_PART_KEY_FLAG) {
1044
+ $flags .= 'part_key ';
1045
+ }
1046
+ if ($f & MYSQLI_SET_FLAG) {
1047
+ $flags .= 'set ';
1048
+ }
1049
+ if ($f & MYSQLI_TIMESTAMP_FLAG) {
1050
+ $flags .= 'timestamp ';
1051
+ }
1052
+ if ($f & MYSQLI_AUTO_INCREMENT_FLAG) {
1053
+ $flags .= 'auto_increment ';
1054
+ }
1055
+ if ($f & MYSQLI_ENUM_FLAG) {
1056
+ $flags .= 'enum ';
1057
+ }
1058
+ // See http://dev.mysql.com/doc/refman/6.0/en/c-api-datatypes.html:
1059
+ // to determine if a string is binary, we should not use MYSQLI_BINARY_FLAG
1060
+ // but instead the charsetnr member of the MYSQL_FIELD
1061
+ // structure. Watch out: some types like DATE returns 63 in charsetnr
1062
+ // so we have to check also the type.
1063
+ // Unfortunately there is no equivalent in the mysql extension.
1064
+ if (($type == MYSQLI_TYPE_TINY_BLOB || $type == MYSQLI_TYPE_BLOB
1065
+ || $type == MYSQLI_TYPE_MEDIUM_BLOB || $type == MYSQLI_TYPE_LONG_BLOB
1066
+ || $type == MYSQLI_TYPE_VAR_STRING || $type == MYSQLI_TYPE_STRING)
1067
+ && 63 == $charsetnr
1068
+ ) {
1069
+ $flags .= 'binary ';
1070
+ }
1071
+ if ($f & MYSQLI_ZEROFILL_FLAG) {
1072
+ $flags .= 'zerofill ';
1073
+ }
1074
+ if ($f & MYSQLI_UNSIGNED_FLAG) {
1075
+ $flags .= 'unsigned ';
1076
+ }
1077
+ if ($f & MYSQLI_BLOB_FLAG) {
1078
+ $flags .= 'blob ';
1079
+ }
1080
+ if ($f & MYSQLI_MULTIPLE_KEY_FLAG) {
1081
+ $flags .= 'multiple_key ';
1082
+ }
1083
+ if ($f & MYSQLI_UNIQUE_KEY_FLAG) {
1084
+ $flags .= 'unique_key ';
1085
+ }
1086
+ if ($f & MYSQLI_PRI_KEY_FLAG) {
1087
+ $flags .= 'primary_key ';
1088
+ }
1089
+ if ($f & MYSQLI_NOT_NULL_FLAG) {
1090
+ $flags .= 'not_null ';
1091
+ }
1092
+ return trim($flags);
1093
+ }
1094
+
1095
+ /**
1096
+ * Returns the text of the error message from previous MySQL/MySQLi operation
1097
+ *
1098
+ * @param string $conn MySQL/MySQLi connection
1099
+ * @returns string Returns the error text from the last MySQL function
1100
+ * @since 1.0
1101
+ */
1102
+ function wpc_mysql_error($conn){
1103
+
1104
+ if(extension_loaded('mysqli')){
1105
+ $return = @mysqli_error($conn);
1106
+
1107
+ // In mysqli if connection is not made then we will get connection error using the following function.
1108
+ if(empty($conn)){
1109
+ $return = @mysqli_connect_error();
1110
+ }
1111
+
1112
+ }else{
1113
+ $return = @mysql_error($conn);
1114
+ }
1115
+
1116
+ return $return;
1117
+ }
1118
+
1119
+ /**
1120
+ * Returns the numerical value of the error message from previous MySQL operation
1121
+ *
1122
+ * @param string $conn MySQL/MySQLi connection
1123
+ * @returns int Returns the error number from the last MySQL function
1124
+ * @since 1.0
1125
+ */
1126
+ function wpc_mysql_errno($conn){
1127
+
1128
+ if(extension_loaded('mysqli')){
1129
+ $return = @mysqli_errno($conn);
1130
+ }else{
1131
+ $return = @mysql_errno($conn);
1132
+ }
1133
+
1134
+ return $return;
1135
+ }
1136
+
1137
+ /**
1138
+ * Retrieves the number of rows from a result set
1139
+ *
1140
+ * @param string $result result resource that is being evaluated
1141
+ * @returns string The number of rows in a result set on success or FALSE on failure
1142
+ * @since 1.0
1143
+ */
1144
+ function wpc_mysql_num_rows($result){
1145
+
1146
+ if(extension_loaded('mysqli')){
1147
+ $return = @mysqli_num_rows($result);
1148
+ }else{
1149
+ $return = @mysql_num_rows($result);
1150
+ }
1151
+
1152
+ return $return;
1153
+ }
1154
+
1155
+ /**
1156
+ * Get number of affected rows in previous MySQL/MySQLi operation
1157
+ *
1158
+ * @param string $conn MySQL/MySQLi connection
1159
+ * @returns int Returns the number of affected rows on success, Zero indicates that no records were updated and -1 if the last query failed.
1160
+ * @since 1.0
1161
+ */
1162
+ function wpc_mysql_affected_rows($conn){
1163
+
1164
+ if(extension_loaded('mysqli')){
1165
+ $return = @mysqli_affected_rows($conn);
1166
+ }else{
1167
+ $return = @mysql_affected_rows($conn);
1168
+ }
1169
+
1170
+ return $return;
1171
+ }
1172
+
1173
+ /**
1174
+ * Get the ID generated in the last query
1175
+ *
1176
+ * @param string $conn MySQL/MySQLi connection
1177
+ * @returns int The ID generated for an AUTO_INCREMENT column by the previous query on success, 0 if the previous query does not generate an AUTO_INCREMENT value, or FALSE if * no MySQL connection was established.
1178
+ * @since 1.0
1179
+ */
1180
+ function wpc_mysql_insert_id($conn){
1181
+
1182
+ if(extension_loaded('mysqli')){
1183
+ $return = @mysqli_insert_id($conn);
1184
+ }else{
1185
+ $return = @mysql_insert_id($conn);
1186
+ }
1187
+
1188
+ return $return;
1189
+ }
1190
+
1191
+ /**
1192
+ * Get number of fields in result
1193
+ *
1194
+ * @param string $result result resource that is being evaluated (Required by MySQL)
1195
+ * @returns string Returns the number of fields in the result set on success or FALSE on failure
1196
+ * @since 1.0
1197
+ */
1198
+ function wpc_mysql_num_fields($result){
1199
+
1200
+ if(extension_loaded('mysqli')){
1201
+ $return = @mysqli_num_fields($result);
1202
+ }else{
1203
+ $return = @mysql_num_fields($result);
1204
+ }
1205
+
1206
+ return $return;
1207
+ }
1208
+
1209
+ /**
1210
+ * Will free all memory associated with the result identifier
1211
+ *
1212
+ * @param string $result result resource that is being evaluated
1213
+ * @returns bool Returns TRUE on success or FALSE on failure
1214
+ * @since 1.0
1215
+ */
1216
+ function wpc_mysql_free_result($result){
1217
+
1218
+ if(extension_loaded('mysqli')){
1219
+ $return = @mysqli_free_result($result);
1220
+ }else{
1221
+ $return = @mysql_free_result($result);
1222
+ }
1223
+
1224
+ return $return;
1225
+ }
1226
+
1227
+ /**
1228
+ * Close MySQL/MySQLi connection
1229
+ *
1230
+ * @param string $conn MySQL/MySQLi connection
1231
+ * @returns bool Returns TRUE on success or FALSE on failure
1232
+ * @since 1.0
1233
+ */
1234
+ function wpc_mysql_close($conn){
1235
+
1236
+ if(extension_loaded('mysqli')){
1237
+ $return = @mysqli_close($conn);
1238
+ }else{
1239
+ $return = @mysql_close($conn);
1240
+ }
1241
+
1242
+ return $return;
1243
+ }
1244
+
1245
+ /**
1246
+ * Get MySQL/MySQLi client info
1247
+ *
1248
+ * @returns string Returns a string that represents the MySQL client library version
1249
+ * @since 1.0
1250
+ */
1251
+ function wpc_mysql_get_client_info(){
1252
+
1253
+ if(extension_loaded('mysqli')){
1254
+ $return = @mysqli_get_client_info();
1255
+ }else{
1256
+ $return = @mysql_get_client_info();
1257
+ }
1258
+
1259
+ return $return;
1260
+ }
1261
+
1262
+ /**
1263
+ * Get MySQL/MySQLi server info
1264
+ *
1265
+ * @param string $conn MySQL/MySQLi connection
1266
+ * @returns string Returns a string that represents the MySQL server version
1267
+ * @since 1.0
1268
+ */
1269
+ function wpc_mysql_get_server_info($conn){
1270
+
1271
+ if(extension_loaded('mysqli')){
1272
+ $return = @mysqli_get_server_info($conn);
1273
+ }else{
1274
+ $return = @mysql_get_server_info($conn);
1275
+ }
1276
+
1277
+ return $return;
1278
+ }
1279
+
1280
+ /**
1281
+ * Execute Database queries
1282
+ *
1283
+ * @param string $queries The Database Queries seperated by a SEMI COLON (;)
1284
+ * @param string $host The Database HOST
1285
+ * @param string $db The Database Name
1286
+ * @param string $user The Database User Name
1287
+ * @param string $pass The Database User Password
1288
+ * @param string $conn The Database Connection
1289
+ * @returns bool
1290
+ * @since 1.0
1291
+ */
1292
+ function wpc_sdb_query($queries, $host, $user, $pass, $db, $conn = '', $no_strict = 0){
1293
+ return wpc_softmysqlfile($queries, $host, $user, $pass, $db, $conn);
1294
+
1295
+ }
1296
+
1297
+ /**
1298
+ * Dump SQL Data ($raw) into the given database.
1299
+ *
1300
+ * @param string $raw The RAW SQL Data
1301
+ * @param string $host The MySQL Host
1302
+ * @param string $user The MySQL User
1303
+ * @param string $pass The MySQL User password
1304
+ * @param string $db The Database Name
1305
+ * @param string $__conn Connection link to the database
1306
+ * @return bool If there is an error $error is filled with the error
1307
+ * @since 1.0
1308
+ */
1309
+ function wpc_softmysqlfile($raw, $host, $user, $pass, $db, $__conn = ""){
1310
+
1311
+ global $error, $l;
1312
+
1313
+ $queries = wpc_sqlsplit($raw);
1314
+
1315
+ //Make the Connection
1316
+ if(empty($__conn)){
1317
+ $__conn = @wpc_mysql_connect($host, $user, $pass, true);
1318
+ }
1319
+
1320
+ //CHECK Errors and SELECT DATABASE
1321
+ if(!empty($__conn)){
1322
+ if(!(@wpc_mysql_select_db($db, $__conn))){
1323
+ $error[] = $l['err_selectmy'].(!empty($_GET['debug']) ? wpc_mysql_error($__conn) : '');
1324
+ return false;
1325
+ }
1326
+ }else{
1327
+ $error[] = $l['err_myconn'].(!empty($_GET['debug']) ? wpc_mysql_error($__conn) : '');
1328
+ return false;
1329
+ }
1330
+
1331
+ $num = count($queries);
1332
+
1333
+ //Start the Queries
1334
+ foreach($queries as $k => $q){
1335
+
1336
+ //PARSE the String and make the QUERY
1337
+ $result = wpc_mysql_query($q, $__conn);
1338
+
1339
+ //Looks like there was an error
1340
+ if(!$result){
1341
+ $error[] = $l['err_makequery'].' : '.$k.'<br />'.$l['err_mynum'].' : '.wpc_mysql_errno($__conn).'<br />'.$l['err_myerr'].' : '.wpc_mysql_error($__conn).(wpc_sdebug('errquery') ? ' Query : '.$q : '');
1342
+ return false;
1343
+ }
1344
+
1345
+ // Is there only one query ?
1346
+ if($num == 1){
1347
+
1348
+ // Is it a SELECT query ?
1349
+ if(preg_match('/^(SELECT|SHOW|DESCRIBE)/is', $q)){ // CHECKSUM|OPTIMIZE|ANALYZE|CHECK|EXPLAIN
1350
+
1351
+ // Accumulate the data !
1352
+ for($i = 0; $i < wpc_mysql_num_rows($result); $i++){
1353
+ $return[] = wpc_mysql_fetch_assoc($result);
1354
+ }
1355
+
1356
+ }
1357
+
1358
+ // Is it a INSERT query ? Then we will have to return insert id
1359
+ if(preg_match('/^INSERT/is', $q)){
1360
+ $return[] = wpc_mysql_insert_id($__conn);
1361
+ }
1362
+ }
1363
+
1364
+ }
1365
+
1366
+ // Are we to return the data ?
1367
+ if(!empty($return)){
1368
+ return $return;
1369
+ }
1370
+
1371
+ return true;
1372
+
1373
+ }
1374
+
1375
+ /**
1376
+ * Is debugging ON for the given key ?
1377
+ *
1378
+ * @param string $key The Key to search for debugging
1379
+ * @return int True on success
1380
+ * @since 1.0
1381
+ */
1382
+ function wpc_sdebug($key){
1383
+ if(@in_array($key, @$_GET['debug']) || @$_GET['debug'] == $key){
1384
+ return true;
1385
+ }
1386
+ }
1387
+
1388
+ /**
1389
+ * phpMyAdmin SPLIT SQL function which splits the SQL data into seperate chunks that can be passed as QUERIES.
1390
+ *
1391
+ * @param string $data The SQL RAW data
1392
+ * @returns array The chunks of SQL Queries
1393
+ * @since 1.0
1394
+ */
1395
+ function wpc_sqlsplit($data){
1396
+
1397
+ $ret = array();
1398
+ $buffer = '';
1399
+ // Defaults for parser
1400
+ $sql = '';
1401
+ $start_pos = 0;
1402
+ $i = 0;
1403
+ $len= 0;
1404
+ $big_value = 200000000;
1405
+ $sql_delimiter = ';';
1406
+
1407
+ $finished = false;
1408
+
1409
+ while (!($finished && $i >= $len)) {
1410
+
1411
+ if ($data === FALSE) {
1412
+ // subtract data we didn't handle yet and stop processing
1413
+ //$offset -= strlen($buffer);
1414
+ break;
1415
+ } elseif ($data === TRUE) {
1416
+ // Handle rest of buffer
1417
+ } else {
1418
+ // Append new data to buffer
1419
+ $buffer .= $data;
1420
+ // free memory
1421
+ $data = false;
1422
+ // Do not parse string when we're not at the end and don't have ; inside
1423
+ if ((strpos($buffer, $sql_delimiter, $i) === FALSE) && !$finished) {
1424
+ continue;
1425
+ }
1426
+ }
1427
+ // Current length of our buffer
1428
+ $len = strlen($buffer);
1429
+
1430
+ // Grab some SQL queries out of it
1431
+ while ($i < $len) {
1432
+ $found_delimiter = false;
1433
+ // Find first interesting character
1434
+ $old_i = $i;
1435
+ // this is about 7 times faster that looking for each sequence i
1436
+ // one by one with strpos()
1437
+ if (preg_match('/(\'|"|#|-- |\/\*|`|(?i)DELIMITER)/', $buffer, $matches, PREG_OFFSET_CAPTURE, $i)) {
1438
+ // in $matches, index 0 contains the match for the complete
1439
+ // expression but we don't use it
1440
+ $first_position = $matches[1][1];
1441
+ } else {
1442
+ $first_position = $big_value;
1443
+ }
1444
+ /**
1445
+ * @todo we should not look for a delimiter that might be
1446
+ * inside quotes (or even double-quotes)
1447
+ */
1448
+ // the cost of doing this one with preg_match() would be too high
1449
+ $first_sql_delimiter = strpos($buffer, $sql_delimiter, $i);
1450
+ if ($first_sql_delimiter === FALSE) {
1451
+ $first_sql_delimiter = $big_value;
1452
+ } else {
1453
+ $found_delimiter = true;
1454
+ }
1455
+
1456
+ // set $i to the position of the first quote, comment.start or delimiter found
1457
+ $i = min($first_position, $first_sql_delimiter);
1458
+
1459
+ if ($i == $big_value) {
1460
+ // none of the above was found in the string
1461
+
1462
+ $i = $old_i;
1463
+ if (!$finished) {
1464
+ break;
1465
+ }
1466
+ // at the end there might be some whitespace...
1467
+ if (trim($buffer) == '') {
1468
+ $buffer = '';
1469
+ $len = 0;
1470
+ break;
1471
+ }
1472
+ // We hit end of query, go there!
1473
+ $i = strlen($buffer) - 1;
1474
+ }
1475
+
1476
+ // Grab current character
1477
+ $ch = $buffer[$i];
1478
+
1479
+ // Quotes
1480
+ if (strpos('\'"`', $ch) !== FALSE) {
1481
+ $quote = $ch;
1482
+ $endq = FALSE;
1483
+ while (!$endq) {
1484
+ // Find next quote
1485
+ $pos = strpos($buffer, $quote, $i + 1);
1486
+ // No quote? Too short string
1487
+ if ($pos === FALSE) {
1488
+ // We hit end of string => unclosed quote, but we handle it as end of query
1489
+ if ($finished) {
1490
+ $endq = TRUE;
1491
+ $i = $len - 1;
1492
+ }
1493
+ $found_delimiter = false;
1494
+ break;
1495
+ }
1496
+ // Was not the quote escaped?
1497
+ $j = $pos - 1;
1498
+ while ($buffer[$j] == '\\') $j--;
1499
+ // Even count means it was not escaped
1500
+ $endq = (((($pos - 1) - $j) % 2) == 0);
1501
+ // Skip the string
1502
+ $i = $pos;
1503
+
1504
+ if ($first_sql_delimiter < $pos) {
1505
+ $found_delimiter = false;
1506
+ }
1507
+ }
1508
+ if (!$endq) {
1509
+ break;
1510
+ }
1511
+ $i++;
1512
+ // Aren't we at the end?
1513
+ if ($finished && $i == $len) {
1514
+ $i--;
1515
+ } else {
1516
+ continue;
1517
+ }
1518
+ }
1519
+
1520
+ // Not enough data to decide
1521
+ if ((($i == ($len - 1) && ($ch == '-' || $ch == '/'))
1522
+ || ($i == ($len - 2) && (($ch == '-' && $buffer[$i + 1] == '-')
1523
+ || ($ch == '/' && $buffer[$i + 1] == '*')))) && !$finished) {
1524
+ break;
1525
+ }
1526
+
1527
+ // Comments
1528
+ if ($ch == '#'
1529
+ || ($i < ($len - 1) && $ch == '-' && $buffer[$i + 1] == '-'
1530
+ && (($i < ($len - 2) && $buffer[$i + 2] <= ' ')
1531
+ || ($i == ($len - 1) && $finished)))
1532
+ || ($i < ($len - 1) && $ch == '/' && $buffer[$i + 1] == '*')
1533
+ ) {
1534
+ // Copy current string to SQL
1535
+ if ($start_pos != $i) {
1536
+ $sql .= substr($buffer, $start_pos, $i - $start_pos);
1537
+ }
1538
+ // Skip the rest
1539
+ $j = $i;
1540
+ $i = strpos($buffer, $ch == '/' ? '*/' : "\n", $i);
1541
+ // didn't we hit end of string?
1542
+ if ($i === FALSE) {
1543
+ if ($finished) {
1544
+ $i = $len - 1;
1545
+ } else {
1546
+ break;
1547
+ }
1548
+ }
1549
+ // Skip *
1550
+ if ($ch == '/') {
1551
+ // Check for MySQL conditional comments and include them as-is
1552
+ if ($buffer[$j + 2] == '!') {
1553
+ $comment = substr($buffer, $j + 3, $i - $j - 3);
1554
+ if (preg_match('/^[0-9]{5}/', $comment, $version)) {
1555
+ if ($version[0] <= 50000000) {
1556
+ $sql .= substr($comment, 5);
1557
+ }
1558
+ } else {
1559
+ $sql .= $comment;
1560
+ }
1561
+ }
1562
+ $i++;
1563
+ }
1564
+ // Skip last char
1565
+ $i++;
1566
+ // Next query part will start here
1567
+ $start_pos = $i;
1568
+ // Aren't we at the end?
1569
+ if ($i == $len) {
1570
+ $i--;
1571
+ } else {
1572
+ continue;
1573
+ }
1574
+ }
1575
+ // Change delimiter, if redefined, and skip it (don't send to server!)
1576
+ if (strtoupper(substr($buffer, $i, 9)) == "DELIMITER"
1577
+ && ($buffer[$i + 9] <= ' ')
1578
+ && ($i < $len - 11)
1579
+ && strpos($buffer, "\n", $i + 11) !== FALSE) {
1580
+ $new_line_pos = strpos($buffer, "\n", $i + 10);
1581
+ $sql_delimiter = substr($buffer, $i + 10, $new_line_pos - $i - 10);
1582
+ $i = $new_line_pos + 1;
1583
+ // Next query part will start here
1584
+ $start_pos = $i;
1585
+ continue;
1586
+ }
1587
+
1588
+ // End of SQL
1589
+ if ($found_delimiter || ($finished && ($i == $len - 1))) {
1590
+ $tmp_sql = $sql;
1591
+ if ($start_pos < $len) {
1592
+ $length_to_grab = $i - $start_pos;
1593
+
1594
+ if (! $found_delimiter) {
1595
+ $length_to_grab++;
1596
+ }
1597
+ $tmp_sql .= substr($buffer, $start_pos, $length_to_grab);
1598
+ unset($length_to_grab);
1599
+ }
1600
+ // Do not try to execute empty SQL
1601
+ if (! preg_match('/^([\s]*;)*$/', trim($tmp_sql))) {
1602
+ $sql = $tmp_sql;
1603
+ $ret[] = $sql;
1604
+
1605
+ $buffer = substr($buffer, $i + strlen($sql_delimiter));
1606
+ // Reset parser:
1607
+ $len = strlen($buffer);
1608
+ $sql = '';
1609
+ $i = 0;
1610
+ $start_pos = 0;
1611
+ // Any chance we will get a complete query?
1612
+ //if ((strpos($buffer, ';') === FALSE) && !$finished) {
1613
+ if ((strpos($buffer, $sql_delimiter) === FALSE) && !$finished) {
1614
+ break;
1615
+ }
1616
+ } else {
1617
+ $i++;
1618
+ $start_pos = $i;
1619
+ }
1620
+ }
1621
+ } // End of parser loop
1622
+ } // End of import loop
1623
+
1624
+ return $ret;
1625
+
1626
+ }
1627
+
1628
+
1629
+ /**
1630
+ * Read the SQL file in parts and Dump the data into the given database
1631
+ *
1632
+ * @param string $file The Path to SQL file
1633
+ * @param string $host The MySQL Host
1634
+ * @param string $user The MySQL User
1635
+ * @param string $pass The MySQL User password
1636
+ * @param string $db The Database Name
1637
+ * @param string $__conn Connection link to the database
1638
+ * @return bool If there is an error $error is filled with the error
1639
+ * @since 1.0
1640
+ */
1641
+ function wpc_soft_mysql_parts($file, $host, $user, $pass, $db, $__conn = "", $delimiter = ';', $replace_data = array()){
1642
+
1643
+ global $__settings, $error, $software, $globals, $l, $softpanel;
1644
+
1645
+ if(is_file($file) === true){
1646
+
1647
+ //Make the Connection
1648
+ if(empty($__conn)){
1649
+ $__conn = @wpc_mysql_connect($host, $user, $pass, true);
1650
+ }
1651
+
1652
+ //CHECK Errors and SELECT DATABASE
1653
+ if(!empty($__conn)){
1654
+ if(!(@wpc_mysql_select_db($db, $__conn))){
1655
+ $error[] = $l['err_selectmy'].(!empty($_GET['debug']) ? wpc_mysql_error($__conn) : '');
1656
+ return false;
1657
+ }
1658
+ }else{
1659
+ $error[] = $l['err_myconn'].(!empty($_GET['debug']) ? wpc_mysql_error($__conn) : '');
1660
+ return false;
1661
+ }
1662
+
1663
+ $file = fopen($file, 'r');
1664
+
1665
+ if(is_resource($file) === true){
1666
+ $query = array();
1667
+ $num = 0;
1668
+ while(feof($file) === false){
1669
+
1670
+ if(is_string($query) === true){
1671
+ $query = array();
1672
+ }
1673
+
1674
+ $query[] = fgets($file);
1675
+
1676
+ if(preg_match('~' . preg_quote($delimiter, '~') . '\s*$~iS', end($query)) === 1){
1677
+ $query = trim(implode('', $query));
1678
+
1679
+ if(!empty($replace_data)){
1680
+ $query = strtr($query, $replace_data);
1681
+ }
1682
+
1683
+ $result = wpc_mysql_query($query, $__conn);
1684
+ if(!$result){
1685
+ $error[] = $l['err_makequery'].' <br />'.$l['err_mynum'].' : '.wpc_mysql_errno($__conn).'<br />'.$l['err_myerr'].' : '.wpc_mysql_error($__conn).(wpc_sdebug('errquery') ? ' Query : '.$query : '');
1686
+ return false;
1687
+ }else{
1688
+ $num++;
1689
+ }
1690
+ }
1691
+ }
1692
+
1693
+ fclose($file);
1694
+
1695
+ // Is there only one query ?
1696
+ if($num == 1){
1697
+
1698
+ // Is it a SELECT query ?
1699
+ if(preg_match('/^(SELECT|SHOW|DESCRIBE)/is', $query)){ // CHECKSUM|OPTIMIZE|ANALYZE|CHECK|EXPLAIN
1700
+
1701
+ // Accumulate the data !
1702
+ for($i = 0; $i < wpc_mysql_num_rows($result); $i++){
1703
+ $return[] = wpc_mysql_fetch_assoc($result);
1704
+ }
1705
+
1706
+ }
1707
+
1708
+ // Is it a INSERT query ? Then we will have to return insert id
1709
+ if(preg_match('/^INSERT/is', $query)){
1710
+ $return[] = wpc_mysql_insert_id($__conn);
1711
+ }
1712
+ }
1713
+
1714
+ // Are we to return the data ?
1715
+ if(!empty($return)){
1716
+ return $return;
1717
+ }
1718
+ }else{
1719
+ $error['err_no_open_db_file'] = $l['err_no_open_db_file'];
1720
+ return false;
1721
+ }
1722
+ }else{
1723
+ $error['err_no_db_file'] = $l['err_no_db_file'];
1724
+ return false;
1725
+ }
1726
+
1727
+ return true;
1728
+ }
1729
+
1730
+ /**
1731
+ * Check whether a file or directory exists at the INSTALLATION level ONLY, not in the PACKAGE
1732
+ *
1733
+ * @param string $path The path of the file or directory
1734
+ * @returns bool
1735
+ * @since 1.0
1736
+ */
1737
+ function wpc_sfile_exists($path){
1738
+ return file_exists($path);
1739
+ }
1740
+
1741
+ /**
1742
+ * Softaculous Version Compare, fixes a bug with '+' as the last character
1743
+ *
1744
+ * @param string $ver1 The first version
1745
+ * @param string $ver2 The second version
1746
+ * @param string $oper By default NULL or operators of the original version_compare() function
1747
+ * @param string $vr By default Empty Array or An array which will contain alphabetic version and to be replace version (For handling alphabatic versions)
1748
+ * @return int values as per the original version_compare() function
1749
+ * @since 1.0
1750
+ */
1751
+ function wpc_sversion_compare($ver1, $ver2, $oper = NULL, $vr = array()){
1752
+
1753
+ if(!empty($vr)){
1754
+ $ver2 = str_replace($vr['search'], $vr['replace'], $ver2);
1755
+ }
1756
+
1757
+ $last1 = substr($ver1, -1);
1758
+ $last2 = substr($ver2, -1);
1759
+
1760
+ if(!preg_match('/[0-9a-zA-Z]/is', $last1)){
1761
+ $ver1 = substr($ver1, 0, -1).'.0'.$last1.'0';
1762
+ }
1763
+
1764
+ if(!preg_match('/[0-9a-zA-Z]/is', $last2)){
1765
+ $ver2 = substr($ver2, 0, -1).'.0'.$last2.'0';
1766
+ }
1767
+
1768
+ if(is_null($oper)){
1769
+ return version_compare($ver1, $ver2);
1770
+ }else{
1771
+ return version_compare($ver1, $ver2, $oper);
1772
+ }
1773
+ }
1774
+
1775
+ /**
1776
+ * Deletes a file. This is meant to be used by install.php, upgrade.php, etc.
1777
+ *
1778
+ * @param string $path
1779
+ * @returns bool
1780
+ * @since 1.0
1781
+ */
1782
+ function wpc_sunlink($path){
1783
+ return @unlink($path);
1784
+ }
1785
+
1786
+ /**
1787
+ * Check whether the path is a directory
1788
+ *
1789
+ * @param string $path The path of the file or directory
1790
+ * @returns bool
1791
+ * @since 1.0
1792
+ */
1793
+ function wpc_is_dir($path){
1794
+ return is_dir($path);
1795
+ }
1796
+
1797
+ /**
1798
+ * Creates a directory. This is meant to be used by install.php, upgrade.php, etc.
1799
+ * NOTE : Folder permissions cannot exceed 0755 in MKDIR. You must use schmod if necessary to give 0777
1800
+ *
1801
+ * @param string $path
1802
+ * @param octal $mode
1803
+ * @param bool $rec Recurse into the directory and apply the changes
1804
+ * @returns bool
1805
+ * @since 1.0
1806
+ */
1807
+ function wpc_mkdir($path, $mode = 0755, $rec = 0){
1808
+ if(!is_dir($path)){
1809
+ $ret = mkdir($path);
1810
+
1811
+ if(!empty($mode)){
1812
+ chmod($path, $mode); // CHMOD to the given OCTAL
1813
+ }
1814
+ return $ret;
1815
+ }
1816
+ return true;
1817
+ }
1818
+
1819
+ /**
1820
+ * Changes the permissions (chmod) of the given path. This is meant to be used by install.php, upgrade.php, etc.
1821
+ *
1822
+ * @param string $path The path of the file or directory
1823
+ * @param octal $oct The new permission e.g. 0644
1824
+ * @returns bool
1825
+ * @since 1.0
1826
+ */
1827
+ function wpc_chmod($path, $mode){
1828
+ return chmod($path, $mode);
1829
+ }
1830
+
1831
+ /**
1832
+ * Writes data to a file
1833
+ *
1834
+ * @param string $file The path of the file or directory
1835
+ * @param string $data Data to write to the file
1836
+ * @returns bool
1837
+ * @since 1.0
1838
+ */
1839
+ function wpc_put($file, $data){
1840
+
1841
+ $fp = @fopen($file, "wb");
1842
+ if($fp){
1843
+ if(@fwrite($fp, $data) === FALSE){
1844
+ return false;
1845
+ }else{
1846
+ @fclose($fp);
1847
+ return true;
1848
+ }
1849
+ }
1850
+ return false;
1851
+ }
1852
+
1853
+ /**
1854
+ * Deletes a file. This is meant to be used by install.php, upgrade.php, etc.
1855
+ *
1856
+ * @param string $filename
1857
+ * @returns bool
1858
+ * @since 1.0
1859
+ */
1860
+ function wpc_delete($filename){
1861
+ return wpc_sunlink($filename);
1862
+ }
1863
+
1864
+ /**
1865
+ * Used in file_functions to perform backup
1866
+ *
1867
+ * @param string $filename
1868
+ * @returns bool
1869
+ * @since 1.0
1870
+ */
1871
+ function wpc_chdir($dir){
1872
+ return wpc_is_dir($dir);
1873
+ }
1874
+
1875
+ /**
1876
+ * Check whether a file or directory exists
1877
+ *
1878
+ * @param string $file The path of the file or directory
1879
+ * @returns bool
1880
+ * @since 1.0
1881
+ */
1882
+ function wpc_file_exists($file){
1883
+ return file_exists($file);
1884
+ }
1885
+
1886
+ /**
1887
+ * Fetch the connection key for the WPC plugin to add the website in WPC panel
1888
+ *
1889
+ * @param bool $force Whether to generate a new key forcefully or fetch the prev generated key
1890
+ * @returns string $conn_key
1891
+ * @since 1.0
1892
+ */
1893
+ function wpc_get_connection_key($force = ''){
1894
+
1895
+ $conn_key = wpc_get_option('wpcentral_auth_key');
1896
+
1897
+ if(empty($conn_key) || $force){
1898
+ $conn_key = wpc_srandstr(128);
1899
+ update_option('wpcentral_auth_key', $conn_key, true);
1900
+ }
1901
+
1902
+ return $conn_key;
1903
+ }
1904
+
1905
+ /**
1906
+ * Calls to generate the connection key on plugin activation
1907
+ *
1908
+ * @returns string $conn_key
1909
+ * @since 1.0
1910
+ */
1911
+ function wpc_activation_hook(){
1912
+ return wpc_get_connection_key(1);
1913
+ }
1914
+
1915
+ /**
1916
+ * Deletes the connection key on plugin deactivation
1917
+ *
1918
+ * @returns bool
1919
+ * @since 1.0
1920
+ */
1921
+ function wpc_deactivation_hook(){
1922
+ return delete_option('wpcentral_auth_key');
1923
+ }
1924
+
1925
+ /**
1926
+ * Add actions and filters on Plugin activation
1927
+ *
1928
+ * @since 1.0
1929
+ */
1930
+ function wpc_on_activation(){
1931
+ global $wpc_slug;
1932
+
1933
+ if(is_plugin_active($wpc_slug)){
1934
+ add_action('admin_init', 'wpc_enqueue_script');
1935
+ add_action('admin_init', 'wpc_enqueue_styles');
1936
+ add_filter( 'plugin_row_meta', 'wpc_add_connection_link', 10, 2 );
1937
+ add_action('admin_head', 'wpc_modal_open_script');
1938
+ add_action('admin_footer', 'wpc_modal_dialog');
1939
+ }
1940
+ }
1941
+
1942
+ /**
1943
+ * Enqueque scripts for WPC plugin
1944
+ *
1945
+ * @since 1.0
1946
+ */
1947
+ function wpc_enqueue_script(){
1948
+ wp_enqueue_script('jquery');
1949
+ wp_enqueue_script('jquery-ui-core');
1950
+ wp_enqueue_script('jquery-ui-dialog');
1951
+ }
1952
+
1953
+ /**
1954
+ * Enqueque styles for WPC plugin
1955
+ *
1956
+ * @since 1.0
1957
+ */
1958
+ function wpc_enqueue_styles(){
1959
+ wp_enqueue_style('wp-jquery-ui');
1960
+ wp_enqueue_style('wp-jquery-ui-dialog');
1961
+ }
1962
+
1963
+ /**
1964
+ * WPC plugin Modal box script
1965
+ *
1966
+ * @since 1.0
1967
+ */
1968
+ function wpc_modal_open_script(){
1969
+
1970
+ $mscript = '<script type="text/javascript">
1971
+ jQuery(document).ready(function($) {
1972
+ var wpc_conn_key_dialog = $("#wpc_connection_key_dialog");
1973
+ $("#wpc_connection_key").click(function(e) {
1974
+ e.preventDefault();
1975
+ wpc_conn_key_dialog.dialog({
1976
+ draggable: false,
1977
+ resizable: false,
1978
+ modal: true,
1979
+ width: "1070px",
1980
+ height: "auto",
1981
+ title: "wpcentral Connection Key",
1982
+ close: function() {
1983
+ $(this).dialog("destroy");
1984
+ }
1985
+ });
1986
+ });
1987
+ });
1988
+ </script>';
1989
+
1990
+ print($mscript);
1991
+ }
1992
+
1993
+ /**
1994
+ * WPC plugin Modal box UI
1995
+ *
1996
+ * @since 1.0
1997
+ */
1998
+ function wpc_modal_dialog(){
1999
+
2000
+ $mdialog = '
2001
+ <div id="wpc_connection_key_dialog" style="display: none;">
2002
+ <p>Follow the steps here to connect your website to wpcentral dashboard:</p>
2003
+ <ol>
2004
+ <li>Copy the connection key below</li>
2005
+ <li>Log into your <a href="https://panel.wpcentral.co/" target="_blank">wpcentral</a> account</li>
2006
+ <li>Click on Add website to add you website to wpcentral.</li>
2007
+ <li>Enter this website\'s URL and paste the Connection key given below.</li>
2008
+ </ol>
2009
+
2010
+ <div style="text-align: center;font-weight: bold;"><p style="margin-bottom: 4px;margin-top: 20px;">wpcentral Connection Key</p></div>
2011
+ <div style="padding: 10px;background-color: #fafafa;border: 1px solid black;border-radius: 10px;font-weight: bold;font-size: 14px;text-align: center;">'.wpc_get_connection_key().'</div>
2012
+ </div>';
2013
+
2014
+ print($mdialog);
2015
+ }
2016
+
2017
+ /**
2018
+ * Add plugin's metadata in the plugin list table
2019
+ *
2020
+ * @param string $links
2021
+ * @param string $slug plugin's slug value
2022
+ * @returns array $links
2023
+ * @since 1.0
2024
+ */
2025
+ function wpc_add_connection_link($links, $slug) {
2026
+ global $wpc_slug;
2027
+
2028
+ if(is_multisite() && is_network_admin()){
2029
+ return $links;
2030
+ }
2031
+
2032
+ if ($slug !== $wpc_slug) {
2033
+ return $links;
2034
+ }
2035
+
2036
+ if(!wpc_current_user_can()){
2037
+ return $links;
2038
+ }
2039
+
2040
+ $new_links = array(
2041
+ 'doc' => '<a href="#" id="wpc_connection_key" value="'.wpc_get_connection_key().'">View Connection Key</a>'
2042
+ );
2043
+
2044
+ $links = array_merge($links, $new_links);
2045
+
2046
+ return $links;
2047
+ }
2048
+
2049
+ /**
2050
+ * Checks whether the current user has a specific capability.
2051
+ *
2052
+ * @param string $can capability name
2053
+ * @returns bool
2054
+ * @since 1.0
2055
+ */
2056
+ function wpc_current_user_can($can = ''){
2057
+ if(empty($can)){
2058
+ $can = 'activate_plugins';
2059
+ }
2060
+
2061
+ require_once(ABSPATH.'wp-includes/pluggable.php');
2062
+ wp_cookie_constants();
2063
+
2064
+ return current_user_can($can);
2065
+ }
2066
+
2067
+ /**
2068
+ * Filters the plugin info.
2069
+ *
2070
+ * @param array $plugins List of all the installed plugins
2071
+ * @returns array $plugins filtered info of the plugins list
2072
+ * @since 1.0
2073
+ */
2074
+ function wpc_plugin_info_filter($plugins){
2075
+ global $wpc_slug;
2076
+
2077
+ if (!isset($plugins[$wpc_slug])){
2078
+ return $plugins;
2079
+ }
2080
+
2081
+ $plugins[$wpc_slug]['Name'] = 'wpcentral';
2082
+ $plugins[$wpc_slug]['Title'] = 'wpcentral';
2083
+ $plugins[$wpc_slug]['Description'] = 'wpcentral provides a centralized area where you can manage all your WordPress websites efficiently, unitedly as well as singularly.';
2084
+ $plugins[$wpc_slug]['AuthorURI'] = 'https://wpcentral.co';
2085
+ $plugins[$wpc_slug]['Author'] = 'Softaculous Ltd.';
2086
+ $plugins[$wpc_slug]['AuthorName'] = 'Softaculous Ltd.';
2087
+ $plugins[$wpc_slug]['PluginURI'] = 'https://wordpress.org/plugins/wp-central/';
2088
+
2089
+ return $plugins;
2090
+ }
2091
+
2092
+ /**
2093
+ * Filters the plugin list.
2094
+ *
2095
+ * @param array $plugins List of all the installed plugins
2096
+ * @returns array $plugins filtered list
2097
+ * @since 1.0
2098
+ */
2099
+ function wpc_plugins_list_filter($plugins){
2100
+
2101
+ return $plugins;
2102
+ }
2103
+
2104
+ ///////////Testing of this requires
2105
+ /**
2106
+ * Hide View plugin details from the plugins page.
2107
+ *
2108
+ * @param array $meta List of plugin information
2109
+ * @param string $slug plugin slug
2110
+ * @returns array $meta
2111
+ * @since 1.0
2112
+ */
2113
+ function wpc_hide_plugin_details($meta, $slug){
2114
+ global $wpc_slug;
2115
+
2116
+ if ($slug !== $wpc_slug) {
2117
+ return $meta;
2118
+ }
2119
+
2120
+ foreach ($meta as $metaKey => $metaValue) {
2121
+ if (strpos($metaValue, sprintf('>%s<', translate('View details'))) === false) {
2122
+ continue;
2123
+ }
2124
+ unset($meta[$metaKey]);
2125
+ break;
2126
+ }
2127
+
2128
+ return $meta;
2129
+ }
2130
+
2131
+ //$updates : List of outdated plugins in response key
2132
+ /**
2133
+ * Hide View plugin details from the plugins page.
2134
+ *
2135
+ * @param $updates List of outdated plugins in response key
2136
+ * @returns $updates
2137
+ * @since 1.0
2138
+ */
2139
+ function wpc_parse_update_plugins($updates){
2140
+ global $wpc_slug;
2141
+
2142
+ if (isset($updates->response[$wpc_slug])) {
2143
+ unset($updates->response[$wpc_slug]);
2144
+ }
2145
+
2146
+ return $updates;
2147
+ }
2148
+
2149
+ /**
2150
+ * Deletes the connection key on plugin deactivation
2151
+ *
2152
+ * @returns bool
2153
+ * @since 1.0
2154
+ */
2155
+ function wpc_deactivate(){
2156
+ delete_option('wpcentral_auth_key');
2157
+ }
2158
+
2159
+ function wpc_authorize(){
2160
+ global $l, $error;
2161
+
2162
+ $auth_key = wpc_optREQ('auth_key');
2163
+ if(empty($auth_key)){
2164
+ $error = 'Unauthorized Access!!';
2165
+ echo json_encode($error);
2166
+ die();
2167
+ }
2168
+
2169
+ $verify_authkey = wpc_get_option('wpcentral_auth_key');
2170
+ if($auth_key != $verify_authkey){
2171
+ $error = $l['invalid_auth_key'];
2172
+ echo json_encode($error);
2173
+ die();
2174
+ }
2175
+ }
2176
+
2177
+ function my_wpc_actions_init(){
2178
+ global $l, $error, $wp_config;
2179
+
2180
+ //Authorize
2181
+ wpc_authorize();
2182
+
2183
+ //Fetch WP Configuration details
2184
+ $wp_config = wpc_fetch_wp_config();
2185
+
2186
+ //Execute the Request
2187
+ $wpc_act = wpc_optREQ('wpc_act');
2188
+
2189
+ switch($wpc_act){
2190
+
2191
+ //The DEFAULT Page
2192
+ default:
2193
+
2194
+ break;
2195
+
2196
+ //The DEFAULT Page
2197
+ case 'verifyconnect':
2198
+ include_once('verify.php');
2199
+ wpc_verify();
2200
+ break;
2201
+
2202
+ case 'getsitedata':
2203
+ include_once('get_site_data.php');
2204
+ wpc_get_site_data();
2205
+ break;
2206
+
2207
+ case 'siteactions':
2208
+ include_once('actions.php');
2209
+ wpc_site_actions();
2210
+ break;
2211
+
2212
+ case 'fileactions':
2213
+ include_once('file_actions.php');
2214
+ wpc_file_actions();
2215
+ break;
2216
+ }
2217
+ }
2218
+
2219
+ function my_wpc_signon(){
2220
+ global $l, $error;
2221
+
2222
+ //Authorize
2223
+ wpc_authorize();
2224
+
2225
+ $user_info = get_userdata(1);
2226
+
2227
+ // Automatic login //
2228
+ $username = $user_info->user_login;
2229
+ $user = get_user_by('login', $username );
2230
+
2231
+ // Redirect URL //
2232
+ if (!is_wp_error($user)){
2233
+ wp_clear_auth_cookie();
2234
+ wp_set_current_user($user->ID);
2235
+ wp_set_auth_cookie($user->ID);
2236
+
2237
+ $redirect_to = user_admin_url();
2238
+ wp_safe_redirect($redirect_to);
2239
+
2240
+ exit();
2241
+ }
2242
+ }
2243
+
2244
+ function admin_notice(){
2245
+ echo '
2246
+ <style>
2247
+ .wpc_sub_head{
2248
+ font-size: 16px !important;
2249
+ color: #676a6c !important;
2250
+ font-weight: bold !important;
2251
+ font-family: OpenSans,Verdana,Tahoma,Arial,Georgia,sans-serif,serif !important;
2252
+ margin-top: 10px !important;
2253
+ }
2254
+
2255
+ .wpc_main_head{
2256
+ font-size: 20px;
2257
+ color: #676a6c;
2258
+ font-family: OpenSans,Verdana,Tahoma,Arial,Georgia,sans-serif,serif;
2259
+ }
2260
+
2261
+ .wpc_flat-butt{
2262
+ text-decoration: none !important;
2263
+ display: inline-block !important;
2264
+ border-radius: 3px !important;
2265
+ font-family: OpenSans, sans-serif !important;
2266
+ font-size: 15px !important;
2267
+ padding: 10px !important;
2268
+ text-align: center !important;
2269
+ border: 0 !important;
2270
+ background: #00a0d2 !important;
2271
+ color: #FFF !important;
2272
+ cursor: pointer !important;
2273
+ outline: 0 !important;
2274
+ font-weight: 400 !important;
2275
+ line-height: 1.42857 !important;
2276
+ text-align: center !important;
2277
+ white-space: nowrap !important;
2278
+ vertical-align: middle !important;
2279
+ -moz-user-select: none !important;
2280
+ border: 1px solid transparent !important;
2281
+ }
2282
+
2283
+ .wpc_flat-butt:hover{
2284
+ background: #46B8DA !important;
2285
+ }
2286
+
2287
+ .wpc_head{
2288
+ font-weight: bold;
2289
+ color: #676a6c;
2290
+ font-family: OpenSans,Verdana,Tahoma,Arial,Georgia,sans-serif,serif;
2291
+ font-size: 13px;
2292
+ }
2293
+
2294
+ .wpc_notice{
2295
+ background-color: #fff;
2296
+ height: 300px;
2297
+ align-items: center;
2298
+ display: flex;
2299
+ text-align: center;
2300
+ border-radius: 6px;
2301
+ box-shadow: 0px 10px 12px -7px #777;
2302
+ border-left-color: unset !important;
2303
+ border-left: unset !important;
2304
+ }
2305
+ </style>
2306
+
2307
+ <div class="updated wpc_notice">
2308
+ <div style="width:100%;">
2309
+ <div class="wpc_main_head">
2310
+ <img src="http://wpcentral.co/images/icon_dark.png" style="height:40px; padding:5px 0;">
2311
+ <img src="http://wpcentral.co/images/logo_dark.png" alt="wpcentral" title="wpcentral" style="height:40px; padding:5px 0;">
2312
+ </div>
2313
+ <div class="wpc_sub_head"><b>Go to <a href="https://panel.wpcentral.co" target="_blank">panel.wpcentral.co</a> and add your website with the following details: </b></div>
2314
+ <div class="wpc_head"><br /><b>Website URL:</b></div><div>'.get_option('siteurl').'</div>
2315
+ <div class="wpc_head"><br /><b>WPCentral Connection Key:</b></div><div>'.get_option('wpcentral_auth_key').'</div><br />
2316
+ <div><a class="wpc_flat-butt wpc_sub_head" href="https://wpcentral.co" target="_blank">Learn More</a></div>
2317
+ </div>
2318
+ </div>';
2319
+ }
wpc_soft_pclzip.php ADDED
@@ -0,0 +1,1531 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Copyright Softaculous Ltd.
4
+
5
+ if (!defined('ABSPATH')){
6
+ exit;
7
+ }
8
+
9
+ if(!class_exists('PclZip')){
10
+ include_once(ABSPATH.'wp-admin/includes/class-pclzip.php');
11
+ }
12
+
13
+ class softpclzip extends PclZip{
14
+
15
+ function __construct($p_zipname){
16
+ return parent::PclZip($p_zipname);
17
+ }
18
+
19
+ function restore_list(){
20
+ $v_result=1;
21
+
22
+ // ----- Reset the error handler
23
+ $this->privErrorReset();
24
+
25
+ // ----- Check archive
26
+ if (!$this->privCheckFormat()) {
27
+ return(0);
28
+ }
29
+
30
+ // ----- Call the extracting fct
31
+ $p_list = array();
32
+
33
+ // ----- Magic quotes trick
34
+ $this->privDisableMagicQuotes();
35
+
36
+ // ----- Open the zip file
37
+ if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
38
+ {
39
+ // ----- Magic quotes trick
40
+ $this->privSwapBackMagicQuotes();
41
+
42
+ // ----- Error log
43
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
44
+
45
+ // ----- Return
46
+ return PclZip::errorCode();
47
+ }
48
+
49
+ // ----- Read the central directory informations
50
+ if (($v_result = $this->restore_privReadEndCentralDir($p_list)) != 1)
51
+ {
52
+ $this->privSwapBackMagicQuotes();
53
+ return $v_result;
54
+ }
55
+
56
+ // ----- Close the zip file
57
+ $this->privCloseFd();
58
+
59
+ // ----- Magic quotes trick
60
+ $this->privSwapBackMagicQuotes();
61
+
62
+ // ----- Return
63
+ return $p_list;
64
+ }
65
+
66
+ function restore_privReadEndCentralDir(&$p_list){
67
+ $v_result=1;
68
+
69
+ $p_central_dir = array();
70
+
71
+ // ----- Go to the end of the zip file
72
+ $v_size = filesize($this->zipname);
73
+ @fseek($this->zip_fd, $v_size);
74
+ if (@ftell($this->zip_fd) != $v_size)
75
+ {
76
+ // ----- Error log
77
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
78
+
79
+ // ----- Return
80
+ return PclZip::errorCode();
81
+ }
82
+
83
+ // ----- First try : look if this is an archive with no commentaries (most of the time)
84
+ // in this case the end of central dir is at 22 bytes of the file end
85
+ $v_found = 0;
86
+ if ($v_size > 26) {
87
+ @fseek($this->zip_fd, $v_size-22);
88
+ if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
89
+ {
90
+ // ----- Error log
91
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
92
+
93
+ // ----- Return
94
+ return PclZip::errorCode();
95
+ }
96
+
97
+ // ----- Read for bytes
98
+ $v_binary_data = @fread($this->zip_fd, 4);
99
+ $v_data = @unpack('Vid', $v_binary_data);
100
+
101
+ // ----- Check signature
102
+ if ($v_data['id'] == 0x06054b50) {
103
+ $v_found = 1;
104
+ }
105
+
106
+ $v_pos = ftell($this->zip_fd);
107
+ }
108
+
109
+ // ----- Go back to the maximum possible size of the Central Dir End Record
110
+ if (!$v_found) {
111
+ $v_maximum_size = 65557; // 0xFFFF + 22;
112
+ if ($v_maximum_size > $v_size)
113
+ $v_maximum_size = $v_size;
114
+ @fseek($this->zip_fd, $v_size-$v_maximum_size);
115
+ if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
116
+ {
117
+ // ----- Error log
118
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
119
+
120
+ // ----- Return
121
+ return PclZip::errorCode();
122
+ }
123
+
124
+ // ----- Read byte per byte in order to find the signature
125
+ $v_pos = ftell($this->zip_fd);
126
+ $v_bytes = 0x00000000;
127
+ while ($v_pos < $v_size)
128
+ {
129
+ // ----- Read a byte
130
+ $v_byte = @fread($this->zip_fd, 1);
131
+
132
+ // ----- Add the byte
133
+ //$v_bytes = ($v_bytes << 8) | Ord($v_byte);
134
+ // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number
135
+ // Otherwise on systems where we have 64bit integers the check below for the magic number will fail.
136
+ $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
137
+
138
+ // ----- Compare the bytes
139
+ if ($v_bytes == 0x504b0506)
140
+ {
141
+ $v_pos++;
142
+ break;
143
+ }
144
+
145
+ $v_pos++;
146
+ }
147
+
148
+ // ----- Look if not found end of central dir
149
+ if ($v_pos == $v_size)
150
+ {
151
+
152
+ // ----- Error log
153
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
154
+
155
+ // ----- Return
156
+ return PclZip::errorCode();
157
+ }
158
+ }
159
+
160
+ // ----- Read the first 18 bytes of the header
161
+ $v_binary_data = fread($this->zip_fd, 18);
162
+
163
+ // ----- Look for invalid block size
164
+ if (strlen($v_binary_data) != 18)
165
+ {
166
+
167
+ // ----- Error log
168
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
169
+
170
+ // ----- Return
171
+ return PclZip::errorCode();
172
+ }
173
+
174
+ // ----- Extract the values
175
+ $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
176
+
177
+ // ----- Check the global size
178
+ if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
179
+
180
+ // ----- Removed in release 2.2 see readme file
181
+ // The check of the file size is a little too strict.
182
+ // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
183
+ // While decrypted, zip has training 0 bytes
184
+ if (0) {
185
+ // ----- Error log
186
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
187
+ 'The central dir is not at the end of the archive.'
188
+ .' Some trailing bytes exists after the archive.');
189
+
190
+ // ----- Return
191
+ return PclZip::errorCode();
192
+ }
193
+ }
194
+
195
+ // ----- Get comment
196
+ if ($v_data['comment_size'] != 0) {
197
+ $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
198
+ }
199
+ else
200
+ $p_central_dir['comment'] = '';
201
+
202
+ $p_central_dir['entries'] = $v_data['entries'];
203
+ $p_central_dir['disk_entries'] = $v_data['disk_entries'];
204
+ $p_central_dir['offset'] = $v_data['offset'];
205
+ $p_central_dir['size'] = $v_data['size'];
206
+ $p_central_dir['disk'] = $v_data['disk'];
207
+ $p_central_dir['disk_start'] = $v_data['disk_start'];
208
+
209
+ //r_print($p_central_dir);
210
+
211
+ // ----- Read next Central dir entry
212
+ @rewind($this->zip_fd);
213
+ if (@fseek($this->zip_fd, $p_central_dir['offset'])){
214
+ return $v_result; // Return the original result
215
+ }
216
+
217
+ //$start = microtime_float();
218
+
219
+ for($i=1; $i<=200000; $i++){
220
+ $binary_data = @fread($this->zip_fd, 4);
221
+ $_data = unpack('Vid', $binary_data);
222
+ if ($_data['id'] != 0x02014b50){
223
+ if($_data['id'] == 0x06054b50){
224
+ $total = $i - 1;
225
+ }
226
+ break;
227
+ }
228
+
229
+ fread($this->zip_fd, 24);
230
+
231
+ $binary_data = fread($this->zip_fd, 6);
232
+ $_header = unpack('vfilename_len/vextra_len/vcomment_len', $binary_data);
233
+
234
+ fread($this->zip_fd, 12);
235
+
236
+ // ----- Get filename
237
+ if ($_header['filename_len'] != 0){
238
+ $filename = fread($this->zip_fd, $_header['filename_len']);
239
+ $vv = trim(trim($filename), '/');
240
+ if(substr_count($vv, '/') || empty($vv)){
241
+
242
+ }else{
243
+ $p_list[] = $vv;
244
+ }
245
+ }
246
+
247
+ // ----- Get extra
248
+ if ($_header['extra_len'] != 0)
249
+ fread($this->zip_fd, $_header['extra_len']);
250
+
251
+ // ----- Get comment
252
+ if ($_header['comment_len'] != 0)
253
+ fread($this->zip_fd, $_header['comment_len']);
254
+
255
+ unset($_header);
256
+
257
+ }// End of for loop
258
+
259
+ if(!empty($total)){
260
+ $p_central_dir['entries'] = $total;
261
+ $p_central_dir['disk_entries'] = $total;
262
+ }
263
+
264
+ // TBC
265
+ //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
266
+ //}
267
+
268
+ // ----- Return
269
+ return $v_result;
270
+ }
271
+
272
+ // Less memory intensive EXTRACT
273
+ function _extract()
274
+ {
275
+ $v_result=1;
276
+
277
+ // ----- Reset the error handler
278
+ $this->privErrorReset();
279
+
280
+ // ----- Check archive
281
+ if (!$this->privCheckFormat()) {
282
+ return(0);
283
+ }
284
+
285
+ // ----- Set default values
286
+ $v_options = array();
287
+ // $v_path = "./";
288
+ $v_path = '';
289
+ $v_remove_path = "";
290
+ $v_remove_all_path = false;
291
+
292
+ // ----- Look for variable options arguments
293
+ $v_size = func_num_args();
294
+
295
+ // ----- Default values for option
296
+ $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
297
+
298
+ // ----- Look for arguments
299
+ if ($v_size > 0) {
300
+ // ----- Get the arguments
301
+ $v_arg_list = func_get_args();
302
+
303
+ // ----- Look for first arg
304
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
305
+
306
+ // ----- Parse the options
307
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
308
+ array (PCLZIP_OPT_PATH => 'optional',
309
+ PCLZIP_OPT_REMOVE_PATH => 'optional',
310
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
311
+ PCLZIP_OPT_ADD_PATH => 'optional',
312
+ PCLZIP_CB_PRE_EXTRACT => 'optional',
313
+ PCLZIP_CB_POST_EXTRACT => 'optional',
314
+ PCLZIP_OPT_SET_CHMOD => 'optional',
315
+ PCLZIP_OPT_BY_NAME => 'optional',
316
+ PCLZIP_OPT_BY_EREG => 'optional',
317
+ PCLZIP_OPT_BY_PREG => 'optional',
318
+ PCLZIP_OPT_BY_INDEX => 'optional',
319
+ PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
320
+ PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
321
+ PCLZIP_OPT_REPLACE_NEWER => 'optional'
322
+ ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
323
+ ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
324
+ PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
325
+ PCLZIP_OPT_TEMP_FILE_ON => 'optional',
326
+ PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
327
+ ));
328
+ if ($v_result != 1) {
329
+ return 0;
330
+ }
331
+
332
+ // ----- Set the arguments
333
+ if (isset($v_options[PCLZIP_OPT_PATH])) {
334
+ $v_path = $v_options[PCLZIP_OPT_PATH];
335
+ }
336
+ if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
337
+ $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
338
+ }
339
+ if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
340
+ $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
341
+ }
342
+ if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
343
+ // ----- Check for '/' in last path char
344
+ if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
345
+ $v_path .= '/';
346
+ }
347
+ $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
348
+ }
349
+ }
350
+
351
+ // ----- Look for 2 args
352
+ // Here we need to support the first historic synopsis of the
353
+ // method.
354
+ else {
355
+
356
+ // ----- Get the first argument
357
+ $v_path = $v_arg_list[0];
358
+
359
+ // ----- Look for the optional second argument
360
+ if ($v_size == 2) {
361
+ $v_remove_path = $v_arg_list[1];
362
+ }
363
+ else if ($v_size > 2) {
364
+ // ----- Error log
365
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
366
+
367
+ // ----- Return
368
+ return 0;
369
+ }
370
+ }
371
+ }
372
+
373
+ // ----- Look for default option values
374
+ $this->privOptionDefaultThreshold($v_options);
375
+
376
+ // ----- Trace
377
+
378
+ // ----- Call the extracting fct
379
+ $p_list = array();
380
+ $v_result = $this->_privExtractByRule($p_list, $v_path, $v_remove_path,
381
+ $v_remove_all_path, $v_options);
382
+ if ($v_result < 1) {
383
+ unset($p_list);
384
+ return(0);
385
+ }
386
+
387
+ // ----- Return
388
+ return $p_list;
389
+ }
390
+
391
+ function _privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
392
+ {
393
+ $v_result=1;
394
+
395
+ // ----- Magic quotes trick
396
+ $this->privDisableMagicQuotes();
397
+
398
+ // ----- Check the path
399
+ if ( ($p_path == "")
400
+ || ( (substr($p_path, 0, 1) != "/")
401
+ && (substr($p_path, 0, 3) != "../")
402
+ && (substr($p_path,1,2)!=":/")))
403
+ $p_path = "./".$p_path;
404
+
405
+ // ----- Reduce the path last (and duplicated) '/'
406
+ if (($p_path != "./") && ($p_path != "/"))
407
+ {
408
+ // ----- Look for the path end '/'
409
+ while (substr($p_path, -1) == "/")
410
+ {
411
+ $p_path = substr($p_path, 0, strlen($p_path)-1);
412
+ }
413
+ }
414
+
415
+ // ----- Look for path to remove format (should end by /)
416
+ if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
417
+ {
418
+ $p_remove_path .= '/';
419
+ }
420
+ $p_remove_path_size = strlen($p_remove_path);
421
+
422
+ // ----- Open the zip file
423
+ if (($v_result = $this->privOpenFd('rb')) != 1)
424
+ {
425
+ $this->privSwapBackMagicQuotes();
426
+ return $v_result;
427
+ }
428
+
429
+ // ----- Read the central directory informations
430
+ $v_central_dir = array();
431
+ if (($v_result = $this->_privReadEndCentralDir($v_central_dir)) != 1)
432
+ {
433
+ // ----- Close the zip file
434
+ $this->privCloseFd();
435
+ $this->privSwapBackMagicQuotes();
436
+
437
+ return $v_result;
438
+ }
439
+
440
+ // ----- Start at beginning of Central Dir
441
+ $v_pos_entry = $v_central_dir['offset'];
442
+
443
+ // ----- Read each entry
444
+ $j_start = 0;
445
+ for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
446
+ {
447
+
448
+ // ----- Read next Central dir entry
449
+ @rewind($this->zip_fd);
450
+ if (@fseek($this->zip_fd, $v_pos_entry))
451
+ {
452
+ // ----- Close the zip file
453
+ $this->privCloseFd();
454
+ $this->privSwapBackMagicQuotes();
455
+
456
+ // ----- Error log
457
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
458
+
459
+ // ----- Return
460
+ return PclZip::errorCode();
461
+ }
462
+
463
+ // ----- Read the file header
464
+ $v_header = array();
465
+ if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
466
+ {
467
+ // ----- Close the zip file
468
+ $this->privCloseFd();
469
+ $this->privSwapBackMagicQuotes();
470
+
471
+ return $v_result;
472
+ }
473
+
474
+ // ----- Store the index
475
+ $v_header['index'] = $i;
476
+
477
+ // ----- Store the file position
478
+ $v_pos_entry = ftell($this->zip_fd);
479
+
480
+ // ----- Look for the specific extract rules
481
+ $v_extract = false;
482
+
483
+ // ----- Look for extract by name rule
484
+ if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
485
+ && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
486
+
487
+ // ----- Look if the filename is in the list
488
+ for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
489
+
490
+ // ----- Look for a directory
491
+ if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
492
+
493
+ // ----- Look if the directory is in the filename path
494
+ if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
495
+ && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
496
+ $v_extract = true;
497
+ }
498
+ }
499
+ // ----- Look for a filename
500
+ elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
501
+ $v_extract = true;
502
+ }
503
+ }
504
+ }
505
+
506
+ // ----- Look for extract by ereg rule
507
+ // ereg() is deprecated with PHP 5.3
508
+ /*
509
+ else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
510
+ && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
511
+
512
+ if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
513
+ $v_extract = true;
514
+ }
515
+ }
516
+ */
517
+
518
+ // ----- Look for extract by preg rule
519
+ else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
520
+ && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
521
+
522
+ if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
523
+ $v_extract = true;
524
+ }
525
+ }
526
+
527
+ // ----- Look for extract by index rule
528
+ else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
529
+ && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
530
+
531
+ // ----- Look if the index is in the list
532
+ for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
533
+
534
+ if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
535
+ $v_extract = true;
536
+ }
537
+ if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
538
+ $j_start = $j+1;
539
+ }
540
+
541
+ if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
542
+ break;
543
+ }
544
+ }
545
+ }
546
+
547
+ // ----- Look for no rule, which means extract all the archive
548
+ else {
549
+ $v_extract = true;
550
+ }
551
+
552
+ // ----- Check compression method
553
+ if ( ($v_extract)
554
+ && ( ($v_header['compression'] != 8)
555
+ && ($v_header['compression'] != 0))) {
556
+ $v_header['status'] = 'unsupported_compression';
557
+
558
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
559
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
560
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
561
+
562
+ $this->privSwapBackMagicQuotes();
563
+
564
+ PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
565
+ "Filename '".$v_header['stored_filename']."' is "
566
+ ."compressed by an unsupported compression "
567
+ ."method (".$v_header['compression'].") ");
568
+
569
+ return PclZip::errorCode();
570
+ }
571
+ }
572
+
573
+ // ----- Check encrypted files
574
+ if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
575
+ $v_header['status'] = 'unsupported_encryption';
576
+
577
+ // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
578
+ if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
579
+ && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
580
+
581
+ $this->privSwapBackMagicQuotes();
582
+
583
+ PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
584
+ "Unsupported encryption for "
585
+ ." filename '".$v_header['stored_filename']
586
+ ."'");
587
+
588
+ return PclZip::errorCode();
589
+ }
590
+ }
591
+
592
+ // ----- Look for real extraction
593
+ if (($v_extract) && ($v_header['status'] != 'ok')) {
594
+ $v_result = $this->privConvertHeader2FileInfo($v_header,
595
+ $p_file_list[$v_nb_extracted++]);
596
+ if ($v_result != 1) {
597
+ $this->privCloseFd();
598
+ $this->privSwapBackMagicQuotes();
599
+ return $v_result;
600
+ }
601
+
602
+ $v_extract = false;
603
+ }
604
+
605
+ // ----- Look for real extraction
606
+ if ($v_extract)
607
+ {
608
+
609
+ // ----- Go to the file position
610
+ @rewind($this->zip_fd);
611
+ if (@fseek($this->zip_fd, $v_header['offset']))
612
+ {
613
+ // ----- Close the zip file
614
+ $this->privCloseFd();
615
+
616
+ $this->privSwapBackMagicQuotes();
617
+
618
+ // ----- Error log
619
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
620
+
621
+ // ----- Return
622
+ return PclZip::errorCode();
623
+ }
624
+
625
+ // ----- Look for extraction as string
626
+ if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
627
+
628
+ $v_string = '';
629
+
630
+ // ----- Extracting the file
631
+ $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
632
+ if ($v_result1 < 1) {
633
+ $this->privCloseFd();
634
+ $this->privSwapBackMagicQuotes();
635
+ return $v_result1;
636
+ }
637
+
638
+ // ----- Get the only interesting attributes
639
+ if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
640
+ {
641
+ // ----- Close the zip file
642
+ $this->privCloseFd();
643
+ $this->privSwapBackMagicQuotes();
644
+
645
+ return $v_result;
646
+ }
647
+
648
+ // ----- Set the file content
649
+ $p_file_list[$v_nb_extracted]['content'] = $v_string;
650
+
651
+ // ----- Next extracted file
652
+ $v_nb_extracted++;
653
+
654
+ // ----- Look for user callback abort
655
+ if ($v_result1 == 2) {
656
+ break;
657
+ }
658
+ }
659
+ // ----- Look for extraction in standard output
660
+ elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
661
+ && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
662
+ // ----- Extracting the file in standard output
663
+ $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
664
+ if ($v_result1 < 1) {
665
+ $this->privCloseFd();
666
+ $this->privSwapBackMagicQuotes();
667
+ return $v_result1;
668
+ }
669
+
670
+ // ----- Get the only interesting attributes
671
+ if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
672
+ $this->privCloseFd();
673
+ $this->privSwapBackMagicQuotes();
674
+ return $v_result;
675
+ }
676
+
677
+ // ----- Look for user callback abort
678
+ if ($v_result1 == 2) {
679
+ break;
680
+ }
681
+ }
682
+ // ----- Look for normal extraction
683
+ else {
684
+ // ----- Extracting the file
685
+ $v_result1 = $this->privExtractFile($v_header,
686
+ $p_path, $p_remove_path,
687
+ $p_remove_all_path,
688
+ $p_options);
689
+ if ($v_result1 < 1) {
690
+ $this->privCloseFd();
691
+ $this->privSwapBackMagicQuotes();
692
+ return $v_result1;
693
+ }
694
+
695
+ $v_nb_extracted++;
696
+
697
+ //echo memory_get_usage().' - '.$v_nb_extracted.' - '.$v_header['filename']."\n";
698
+
699
+ // ----- Get the only interesting attributes
700
+ /*if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
701
+ {
702
+ // ----- Close the zip file
703
+ $this->privCloseFd();
704
+ $this->privSwapBackMagicQuotes();
705
+
706
+ return $v_result;
707
+ }*/
708
+
709
+ // ----- Look for user callback abort
710
+ if ($v_result1 == 2) {
711
+ break;
712
+ }
713
+ }
714
+ }
715
+ }
716
+
717
+ // ----- Close the zip file
718
+ $this->privCloseFd();
719
+ $this->privSwapBackMagicQuotes();
720
+
721
+ // ----- Return
722
+ return $v_result;
723
+ }
724
+
725
+ function _privReadEndCentralDir(&$p_central_dir)
726
+ {
727
+ $v_result=1;
728
+
729
+ // ----- Go to the end of the zip file
730
+ $v_size = filesize($this->zipname);
731
+ @fseek($this->zip_fd, $v_size);
732
+ if (@ftell($this->zip_fd) != $v_size)
733
+ {
734
+ // ----- Error log
735
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
736
+
737
+ // ----- Return
738
+ return PclZip::errorCode();
739
+ }
740
+
741
+ // ----- First try : look if this is an archive with no commentaries (most of the time)
742
+ // in this case the end of central dir is at 22 bytes of the file end
743
+ $v_found = 0;
744
+ if ($v_size > 26) {
745
+ @fseek($this->zip_fd, $v_size-22);
746
+ if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
747
+ {
748
+ // ----- Error log
749
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
750
+
751
+ // ----- Return
752
+ return PclZip::errorCode();
753
+ }
754
+
755
+ // ----- Read for bytes
756
+ $v_binary_data = @fread($this->zip_fd, 4);
757
+ $v_data = @unpack('Vid', $v_binary_data);
758
+
759
+ // ----- Check signature
760
+ if ($v_data['id'] == 0x06054b50) {
761
+ $v_found = 1;
762
+ }
763
+
764
+ $v_pos = ftell($this->zip_fd);
765
+ }
766
+
767
+ // ----- Go back to the maximum possible size of the Central Dir End Record
768
+ if (!$v_found) {
769
+ $v_maximum_size = 65557; // 0xFFFF + 22;
770
+ if ($v_maximum_size > $v_size)
771
+ $v_maximum_size = $v_size;
772
+ @fseek($this->zip_fd, $v_size-$v_maximum_size);
773
+ if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
774
+ {
775
+ // ----- Error log
776
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
777
+
778
+ // ----- Return
779
+ return PclZip::errorCode();
780
+ }
781
+
782
+ // ----- Read byte per byte in order to find the signature
783
+ $v_pos = ftell($this->zip_fd);
784
+ $v_bytes = 0x00000000;
785
+ while ($v_pos < $v_size)
786
+ {
787
+ // ----- Read a byte
788
+ $v_byte = @fread($this->zip_fd, 1);
789
+
790
+ // ----- Add the byte
791
+ //$v_bytes = ($v_bytes << 8) | Ord($v_byte);
792
+ // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number
793
+ // Otherwise on systems where we have 64bit integers the check below for the magic number will fail.
794
+ $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
795
+
796
+ // ----- Compare the bytes
797
+ if ($v_bytes == 0x504b0506)
798
+ {
799
+ $v_pos++;
800
+ break;
801
+ }
802
+
803
+ $v_pos++;
804
+ }
805
+
806
+ // ----- Look if not found end of central dir
807
+ if ($v_pos == $v_size)
808
+ {
809
+
810
+ // ----- Error log
811
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
812
+
813
+ // ----- Return
814
+ return PclZip::errorCode();
815
+ }
816
+ }
817
+
818
+ // ----- Read the first 18 bytes of the header
819
+ $v_binary_data = fread($this->zip_fd, 18);
820
+
821
+ // ----- Look for invalid block size
822
+ if (strlen($v_binary_data) != 18)
823
+ {
824
+
825
+ // ----- Error log
826
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
827
+
828
+ // ----- Return
829
+ return PclZip::errorCode();
830
+ }
831
+
832
+ // ----- Extract the values
833
+ $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
834
+
835
+ // ----- Check the global size
836
+ if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
837
+
838
+ // ----- Removed in release 2.2 see readme file
839
+ // The check of the file size is a little too strict.
840
+ // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
841
+ // While decrypted, zip has training 0 bytes
842
+ if (0) {
843
+ // ----- Error log
844
+ PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
845
+ 'The central dir is not at the end of the archive.'
846
+ .' Some trailing bytes exists after the archive.');
847
+
848
+ // ----- Return
849
+ return PclZip::errorCode();
850
+ }
851
+ }
852
+
853
+ // ----- Get comment
854
+ if ($v_data['comment_size'] != 0) {
855
+ $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
856
+ }
857
+ else
858
+ $p_central_dir['comment'] = '';
859
+
860
+ $p_central_dir['entries'] = $v_data['entries'];
861
+ $p_central_dir['disk_entries'] = $v_data['disk_entries'];
862
+ $p_central_dir['offset'] = $v_data['offset'];
863
+ $p_central_dir['size'] = $v_data['size'];
864
+ $p_central_dir['disk'] = $v_data['disk'];
865
+ $p_central_dir['disk_start'] = $v_data['disk_start'];
866
+
867
+ //r_print($p_central_dir);
868
+
869
+ // ----- Read next Central dir entry
870
+ @rewind($this->zip_fd);
871
+ if (@fseek($this->zip_fd, $p_central_dir['offset'])){
872
+ return $v_result; // Return the original result
873
+ }
874
+
875
+ //$start = microtime_float();
876
+
877
+ for($i=1; $i<=200000; $i++){
878
+ $binary_data = @fread($this->zip_fd, 4);
879
+ $_data = unpack('Vid', $binary_data);
880
+ if ($_data['id'] != 0x02014b50){
881
+ if($_data['id'] == 0x06054b50){
882
+ $total = $i - 1;
883
+ }
884
+ break;
885
+ }
886
+
887
+ fread($this->zip_fd, 24);
888
+
889
+ $binary_data = fread($this->zip_fd, 6);
890
+ $_header = unpack('vfilename_len/vextra_len/vcomment_len', $binary_data);
891
+
892
+ fread($this->zip_fd, 12);
893
+
894
+ // ----- Get filename
895
+ if ($_header['filename_len'] != 0)
896
+ fread($this->zip_fd, $_header['filename_len']);
897
+
898
+ // ----- Get extra
899
+ if ($_header['extra_len'] != 0)
900
+ fread($this->zip_fd, $_header['extra_len']);
901
+
902
+ // ----- Get comment
903
+ if ($_header['comment_len'] != 0)
904
+ fread($this->zip_fd, $_header['comment_len']);
905
+
906
+ unset($_header);
907
+
908
+ }// End of for loop
909
+
910
+ if(!empty($total)){
911
+ $p_central_dir['entries'] = $total;
912
+ $p_central_dir['disk_entries'] = $total;
913
+ }
914
+
915
+ //echo (microtime_float() - $start)."\n";
916
+
917
+ //r_print($p_central_dir);
918
+
919
+ // TBC
920
+ //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
921
+ //}
922
+
923
+ // ----- Return
924
+ return $v_result;
925
+ }
926
+
927
+ function _add($p_filelist)
928
+ {
929
+ $v_result=1;
930
+
931
+ // ----- Reset the error handler
932
+ $this->privErrorReset();
933
+
934
+ // ----- Set default values
935
+ $v_options = array();
936
+ $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
937
+
938
+ // ----- Look for variable options arguments
939
+ $v_size = func_num_args();
940
+
941
+ // ----- Look for arguments
942
+ if ($v_size > 1) {
943
+ // ----- Get the arguments
944
+ $v_arg_list = func_get_args();
945
+
946
+ // ----- Remove form the options list the first argument
947
+ array_shift($v_arg_list);
948
+ $v_size--;
949
+
950
+ // ----- Look for first arg
951
+ if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
952
+
953
+ // ----- Parse the options
954
+ $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
955
+ array (PCLZIP_OPT_REMOVE_PATH => 'optional',
956
+ PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
957
+ PCLZIP_OPT_ADD_PATH => 'optional',
958
+ PCLZIP_CB_PRE_ADD => 'optional',
959
+ PCLZIP_CB_POST_ADD => 'optional',
960
+ PCLZIP_OPT_NO_COMPRESSION => 'optional',
961
+ PCLZIP_OPT_COMMENT => 'optional',
962
+ PCLZIP_OPT_ADD_COMMENT => 'optional',
963
+ PCLZIP_OPT_PREPEND_COMMENT => 'optional',
964
+ PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
965
+ PCLZIP_OPT_TEMP_FILE_ON => 'optional',
966
+ PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
967
+ //, PCLZIP_OPT_CRYPT => 'optional'
968
+ ));
969
+ if ($v_result != 1) {
970
+ return 0;
971
+ }
972
+ }
973
+
974
+ // ----- Look for 2 args
975
+ // Here we need to support the first historic synopsis of the
976
+ // method.
977
+ else {
978
+
979
+ // ----- Get the first argument
980
+ $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
981
+
982
+ // ----- Look for the optional second argument
983
+ if ($v_size == 2) {
984
+ $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
985
+ }
986
+ else if ($v_size > 2) {
987
+ // ----- Error log
988
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
989
+
990
+ // ----- Return
991
+ return 0;
992
+ }
993
+ }
994
+ }
995
+
996
+ // ----- Look for default option values
997
+ $this->privOptionDefaultThreshold($v_options);
998
+
999
+ // ----- Init
1000
+ $v_string_list = array();
1001
+ $v_att_list = array();
1002
+ $v_filedescr_list = array();
1003
+ $p_result_list = array();
1004
+
1005
+ // ----- Look if the $p_filelist is really an array
1006
+ if (is_array($p_filelist)) {
1007
+
1008
+ // ----- Look if the first element is also an array
1009
+ // This will mean that this is a file description entry
1010
+ if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
1011
+ $v_att_list = $p_filelist;
1012
+ }
1013
+
1014
+ // ----- The list is a list of string names
1015
+ else {
1016
+ $v_string_list = $p_filelist;
1017
+ }
1018
+ }
1019
+
1020
+ // ----- Look if the $p_filelist is a string
1021
+ else if (is_string($p_filelist)) {
1022
+ // ----- Create a list from the string
1023
+ $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
1024
+ }
1025
+
1026
+ // ----- Invalid variable type for $p_filelist
1027
+ else {
1028
+ PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
1029
+ return 0;
1030
+ }
1031
+
1032
+ // ----- Reformat the string list
1033
+ if (sizeof($v_string_list) != 0) {
1034
+ foreach ($v_string_list as $v_string) {
1035
+ $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
1036
+ }
1037
+ }
1038
+
1039
+ // ----- For each file in the list check the attributes
1040
+ $v_supported_attributes
1041
+ = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
1042
+ ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
1043
+ ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
1044
+ ,PCLZIP_ATT_FILE_MTIME => 'optional'
1045
+ ,PCLZIP_ATT_FILE_CONTENT => 'optional'
1046
+ ,PCLZIP_ATT_FILE_COMMENT => 'optional'
1047
+ );
1048
+ foreach ($v_att_list as $v_entry) {
1049
+ $v_result = $this->privFileDescrParseAtt($v_entry,
1050
+ $v_filedescr_list[],
1051
+ $v_options,
1052
+ $v_supported_attributes);
1053
+ if ($v_result != 1) {
1054
+ return 0;
1055
+ }
1056
+ }
1057
+
1058
+ /*// ----- Expand the filelist (expand directories)
1059
+ $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
1060
+ if ($v_result != 1) {
1061
+ return 0;
1062
+ }*/
1063
+
1064
+ // ----- Call the create fct
1065
+ $v_result = $this->_privAdd($v_filedescr_list, $p_result_list, $v_options);
1066
+ if ($v_result != 1) {
1067
+ return 0;
1068
+ }
1069
+
1070
+ // ----- Return
1071
+ return $p_result_list;
1072
+ }
1073
+
1074
+ function _privAdd($p_filedescr_list, &$p_result_list, &$p_options)
1075
+ {
1076
+ $v_result=1;
1077
+ $v_list_detail = array();
1078
+
1079
+ // ----- Look if the archive exists or is empty
1080
+ if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
1081
+ {
1082
+
1083
+ $v_result = $this->privFileDescrExpand($p_filedescr_list, $p_options);
1084
+ if ($v_result != 1) {
1085
+ return 0;
1086
+ }
1087
+
1088
+ // ----- Do a create
1089
+ $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
1090
+
1091
+ // ----- Return
1092
+ return $v_result;
1093
+ }
1094
+ // ----- Magic quotes trick
1095
+ $this->privDisableMagicQuotes();
1096
+
1097
+ // ----- Open the zip file
1098
+ if (($v_result=$this->privOpenFd('rb')) != 1)
1099
+ {
1100
+ // ----- Magic quotes trick
1101
+ $this->privSwapBackMagicQuotes();
1102
+
1103
+ // ----- Return
1104
+ return $v_result;
1105
+ }
1106
+
1107
+ // ----- Read the central directory informations
1108
+ $v_central_dir = array();
1109
+ if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
1110
+ {
1111
+ $this->privCloseFd();
1112
+ $this->privSwapBackMagicQuotes();
1113
+ return $v_result;
1114
+ }
1115
+
1116
+ // ----- Go to beginning of File
1117
+ @rewind($this->zip_fd);
1118
+
1119
+ // ----- Creates a temporay file
1120
+ $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
1121
+
1122
+ // ----- Open the temporary file in write mode
1123
+ if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
1124
+ {
1125
+ $this->privCloseFd();
1126
+ $this->privSwapBackMagicQuotes();
1127
+
1128
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
1129
+
1130
+ // ----- Return
1131
+ return PclZip::errorCode();
1132
+ }
1133
+
1134
+ // ----- Copy the files from the archive to the temporary file
1135
+ // TBC : Here I should better append the file and go back to erase the central dir
1136
+ $v_size = $v_central_dir['offset'];
1137
+ while ($v_size != 0)
1138
+ {
1139
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
1140
+ $v_buffer = fread($this->zip_fd, $v_read_size);
1141
+ @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
1142
+ $v_size -= $v_read_size;
1143
+ }
1144
+
1145
+ // ----- Swap the file descriptor
1146
+ // Here is a trick : I swap the temporary fd with the zip fd, in order to use
1147
+ // the following methods on the temporary fil and not the real archive
1148
+ $v_swap = $this->zip_fd;
1149
+ $this->zip_fd = $v_zip_temp_fd;
1150
+ $v_zip_temp_fd = $v_swap;
1151
+
1152
+ global $tempheader;
1153
+
1154
+ $tempheader = '';
1155
+
1156
+ $tempheaderfile = PCLZIP_TEMPORARY_DIR.uniqid('softaculous').'.tmp';
1157
+ if(($tempheader = @fopen($tempheaderfile, 'wb')) == 0){
1158
+ fclose($v_zip_temp_fd);
1159
+ $this->privCloseFd();
1160
+ @unlink($v_zip_temp_name);
1161
+ $this->privSwapBackMagicQuotes();
1162
+ PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$tempheaderfile.'\' in binary write mode');
1163
+ return 88888;
1164
+ }
1165
+
1166
+ //echo 'privAddList - '.memory_get_usage()."\n";
1167
+
1168
+ // ----- Add the files
1169
+ if (($v_result = $this->_privAddFileList($p_filedescr_list, $p_result_list, $p_options)) != 1)
1170
+ {
1171
+ fclose($v_zip_temp_fd);
1172
+ $this->privCloseFd();
1173
+ @unlink($v_zip_temp_name);
1174
+ $this->privSwapBackMagicQuotes();
1175
+
1176
+ // ----- Return
1177
+ return $v_result;
1178
+ }
1179
+
1180
+ //echo 'privAddList END - '.memory_get_usage()."\n";
1181
+
1182
+ // ----- Store the offset of the central dir
1183
+ $v_offset = @ftell($this->zip_fd);
1184
+
1185
+ //echo '1 - '.memory_get_usage()."\n";
1186
+ // ----- Copy the block of file headers from the old archive
1187
+ $v_size = $v_central_dir['size'];
1188
+ while ($v_size != 0)
1189
+ {
1190
+ $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
1191
+ $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
1192
+ @fwrite($this->zip_fd, $v_buffer, $v_read_size);
1193
+ $v_size -= $v_read_size;
1194
+ }
1195
+
1196
+ //echo '2 - '.memory_get_usage()."\n";
1197
+ // ----- Create the Central Dir files header
1198
+ $v_count = $p_result_list;
1199
+
1200
+ // Append the Temporary file we created.
1201
+ @fclose($tempheader);
1202
+
1203
+ if(($tempfd = @fopen($tempheaderfile, "rb")) == 0){
1204
+ fclose($v_zip_temp_fd);
1205
+ $this->privCloseFd();
1206
+ @unlink($v_zip_temp_name);
1207
+ $this->privSwapBackMagicQuotes();
1208
+ return 88888;
1209
+ }
1210
+
1211
+ $t_size = filesize($tempheaderfile);
1212
+ while ($t_size != 0)
1213
+ {
1214
+ $t_read_size = ($t_size < PCLZIP_READ_BLOCK_SIZE ? $t_size : PCLZIP_READ_BLOCK_SIZE);
1215
+ $t_buffer = @fread($tempfd, $t_read_size);
1216
+ @fwrite($this->zip_fd, $t_buffer, $t_read_size);
1217
+ $t_size -= $t_read_size;
1218
+ }
1219
+
1220
+ @fclose($tempfd);
1221
+ @unlink($tempheaderfile);
1222
+
1223
+ //echo '3 - '.memory_get_usage()."\n";
1224
+ // ----- Zip file comment
1225
+ $v_comment = $v_central_dir['comment'];
1226
+ if (isset($p_options[PCLZIP_OPT_COMMENT])) {
1227
+ $v_comment = $p_options[PCLZIP_OPT_COMMENT];
1228
+ }
1229
+ if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
1230
+ $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
1231
+ }
1232
+ if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
1233
+ $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
1234
+ }
1235
+ //echo '4 - '.memory_get_usage()."\n";
1236
+ // ----- Calculate the size of the central header
1237
+ $v_size = @ftell($this->zip_fd)-$v_offset;
1238
+
1239
+ // ----- Create the central dir footer
1240
+ if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
1241
+ {
1242
+ // ----- Reset the file list
1243
+
1244
+ $this->privSwapBackMagicQuotes();
1245
+
1246
+ // ----- Return
1247
+ return $v_result;
1248
+ }
1249
+ //echo '5 - '.memory_get_usage()."\n";
1250
+ // ----- Swap back the file descriptor
1251
+ $v_swap = $this->zip_fd;
1252
+ $this->zip_fd = $v_zip_temp_fd;
1253
+ $v_zip_temp_fd = $v_swap;
1254
+ //echo '6 - '.memory_get_usage()."\n";
1255
+ // ----- Close
1256
+ $this->privCloseFd();
1257
+ //echo '7 - '.memory_get_usage()."\n";
1258
+ // ----- Close the temporary file
1259
+ @fclose($v_zip_temp_fd);
1260
+
1261
+ // ----- Magic quotes trick
1262
+ $this->privSwapBackMagicQuotes();
1263
+ //echo '8 - '.memory_get_usage()."\n";
1264
+ // ----- Delete the zip file
1265
+ // TBC : I should test the result ...
1266
+ @unlink($this->zipname);
1267
+
1268
+ // ----- Rename the temporary file
1269
+ // TBC : I should test the result ...
1270
+ //@rename($v_zip_temp_name, $this->zipname);
1271
+ PclZipUtilRename($v_zip_temp_name, $this->zipname);
1272
+ //echo '9 - '.memory_get_usage()."\n";
1273
+ // ----- Return
1274
+ return $v_result;
1275
+ }
1276
+
1277
+ function _privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
1278
+ {
1279
+ $v_result=1;
1280
+
1281
+ global $_soft_result_list, $_soft_nb;
1282
+
1283
+ $_soft_result_list = array();
1284
+ $_soft_nb = 0;
1285
+
1286
+ $v_result = $this->_privFileDescrExpand($p_filedescr_list, $p_options);
1287
+ if ($v_result != 1) {
1288
+ return 0;
1289
+ }
1290
+
1291
+ $p_result_list = $_soft_nb;
1292
+
1293
+ // ----- Return
1294
+ return $v_result;
1295
+ }
1296
+
1297
+ function _privFileDescrExpand(&$p_filedescr_list, &$p_options)
1298
+ {
1299
+ global $error, $l;
1300
+ $v_result=1;
1301
+
1302
+ // ----- Create a result list
1303
+ $v_result_list = array();
1304
+ // r_print($p_filedescr_list);
1305
+
1306
+ // ----- Look each entry
1307
+ for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
1308
+ // ----- Get filedescr
1309
+ $v_descr = $p_filedescr_list[$i];
1310
+
1311
+ // ----- Reduce the filename
1312
+ $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
1313
+ $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
1314
+
1315
+ // ----- Look for real file or folder
1316
+ if (file_exists($v_descr['filename'])) {
1317
+ if (@is_file($v_descr['filename'])) {
1318
+ $v_descr['type'] = 'file';
1319
+ }
1320
+ else if (@is_dir($v_descr['filename'])) {
1321
+ $v_descr['type'] = 'folder';
1322
+ }
1323
+ else if (@is_link($v_descr['filename'])) {
1324
+ // skip
1325
+ continue;
1326
+ }
1327
+ else {
1328
+ // skip
1329
+ continue;
1330
+ }
1331
+ }
1332
+
1333
+ // ----- Look for string added as file
1334
+ else if (isset($v_descr['content'])) {
1335
+ $v_descr['type'] = 'virtual_file';
1336
+ }
1337
+
1338
+ // ----- Missing file
1339
+ else {
1340
+ $error['read'] = lang_vars($l['could_not_read'], array($v_descr['filename']));
1341
+ // ----- Error log
1342
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");
1343
+ // ----- Return
1344
+ return PclZip::errorCode();
1345
+ }
1346
+
1347
+ // ----- Calculate the stored filename
1348
+ $this->privCalculateStoredFilename($v_descr, $p_options);
1349
+ //r_print($v_descr);
1350
+
1351
+ ///////////////////////////////////////
1352
+ // Softaculous Change
1353
+ // We add the files here itself
1354
+ ///////////////////////////////////////
1355
+
1356
+ global $_soft_result_list, $_soft_nb;
1357
+
1358
+ $_file = $v_descr;
1359
+
1360
+ // ----- Format the filename
1361
+ $_file['filename'] = PclZipUtilTranslateWinPath($_file['filename'], false);
1362
+
1363
+ // ----- Skip empty file names
1364
+ // TBC : Can this be possible ? not checked in DescrParseAtt ?
1365
+ if ($_file['filename'] == "") {
1366
+ continue;
1367
+ }
1368
+
1369
+ // ----- Check the filename
1370
+ if ( ($_file['type'] != 'virtual_file')
1371
+ && (!file_exists($_file['filename']))) {
1372
+ PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$_file['filename']."' does not exist");
1373
+ return PclZip::errorCode();
1374
+ }
1375
+
1376
+ // ----- Look if it is a file or a dir with no all path remove option
1377
+ // or a dir with all its path removed
1378
+ // if ( (is_file($p_filedescr_list[$j]['filename']))
1379
+ // || ( is_dir($p_filedescr_list[$j]['filename'])
1380
+ if ( ($_file['type'] == 'file')
1381
+ || ($_file['type'] == 'virtual_file')
1382
+ || ( ($_file['type'] == 'folder')
1383
+ && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
1384
+ || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
1385
+ ) {
1386
+
1387
+ $v_header = array();
1388
+
1389
+ // ----- Add the file
1390
+ $v_result = $this->privAddFile($_file, $v_header, $p_options);
1391
+ if ($v_result != 1) {
1392
+ return $v_result;
1393
+ }
1394
+
1395
+ if ($v_header['status'] == 'ok') {
1396
+ if (($v_result = $this->_privWriteCentralFileHeader($v_header)) != 1) {
1397
+ // ----- Return
1398
+ return $v_result;
1399
+ }
1400
+
1401
+ $_soft_nb++;
1402
+ }
1403
+
1404
+ unset($v_header);
1405
+
1406
+ // ----- Store the file infos
1407
+ //$_soft_result_list[$_soft_nb++] = $v_header;
1408
+
1409
+ }
1410
+ ////////////////////////////////////////
1411
+ // End of Adding the Files
1412
+ ////////////////////////////////////////
1413
+
1414
+ // ----- Add the descriptor in result list
1415
+ $v_result_list[sizeof($v_result_list)] = $v_descr;
1416
+ //r_print($v_descr);
1417
+ // ----- Look for folder
1418
+ if ($v_descr['type'] == 'folder') {
1419
+ // ----- List of items in folder
1420
+ $v_dirlist_descr = array();
1421
+ $v_dirlist_nb = 0;
1422
+ if (($v_folder_handler = @opendir($v_descr['filename']))) {
1423
+ while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
1424
+
1425
+ // ----- Skip '.' and '..'
1426
+ if (($v_item_handler == '.') || ($v_item_handler == '..')) {
1427
+ continue;
1428
+ }
1429
+
1430
+ // ----- Compose the full filename
1431
+ $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
1432
+
1433
+ // ----- Look for different stored filename
1434
+ // Because the name of the folder was changed, the name of the
1435
+ // files/sub-folders also change
1436
+ if (($v_descr['stored_filename'] != $v_descr['filename'])
1437
+ && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
1438
+ if ($v_descr['stored_filename'] != '') {
1439
+ $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
1440
+ }
1441
+ else {
1442
+ $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
1443
+ }
1444
+ }
1445
+ $v_dirlist_nb++;
1446
+ //echo $v_dirlist_nb."\n";
1447
+ }
1448
+
1449
+ @closedir($v_folder_handler);
1450
+ }
1451
+ else {
1452
+ // TBC : unable to open folder in read mode
1453
+ }
1454
+
1455
+ //r_print($v_dirlist_descr);
1456
+
1457
+ // ----- Expand each element of the list
1458
+ if ($v_dirlist_nb != 0) {
1459
+ // ----- Expand
1460
+ if (($v_result = $this->_privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
1461
+ return $v_result;
1462
+ }
1463
+
1464
+ // ----- Concat the resulting list
1465
+ //$v_result_list = array_merge($v_result_list, $v_dirlist_descr);
1466
+ }
1467
+ else {
1468
+ }
1469
+
1470
+ // ----- Free local array
1471
+ unset($v_dirlist_descr);
1472
+ }
1473
+ }
1474
+
1475
+ // ----- Get the result list
1476
+ //$p_filedescr_list = $v_result_list;
1477
+
1478
+ // ----- Return
1479
+ return $v_result;
1480
+ }
1481
+
1482
+ function _privWriteCentralFileHeader(&$p_header)
1483
+ {
1484
+ $v_result=1;
1485
+
1486
+ global $tempheader;
1487
+
1488
+ // TBC
1489
+ //for(reset($p_header); $key = key($p_header); next($p_header)) {
1490
+ //}
1491
+
1492
+ // ----- Transform UNIX mtime to DOS format mdate/mtime
1493
+ $v_date = getdate($p_header['mtime']);
1494
+ $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
1495
+ $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
1496
+
1497
+
1498
+ // ----- Packed data
1499
+ $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
1500
+ $p_header['version'], $p_header['version_extracted'],
1501
+ $p_header['flag'], $p_header['compression'],
1502
+ $v_mtime, $v_mdate, $p_header['crc'],
1503
+ $p_header['compressed_size'], $p_header['size'],
1504
+ strlen($p_header['stored_filename']),
1505
+ $p_header['extra_len'], $p_header['comment_len'],
1506
+ $p_header['disk'], $p_header['internal'],
1507
+ $p_header['external'], $p_header['offset']);
1508
+
1509
+ // ----- Write the 42 bytes of the header in the zip file
1510
+ fputs($tempheader, $v_binary_data, 46);
1511
+
1512
+ // ----- Write the variable fields
1513
+ if (strlen($p_header['stored_filename']) != 0)
1514
+ {
1515
+ fputs($tempheader, $p_header['stored_filename'], strlen($p_header['stored_filename']));
1516
+ }
1517
+ if ($p_header['extra_len'] != 0)
1518
+ {
1519
+ fputs($tempheader, $p_header['extra'], $p_header['extra_len']);
1520
+ }
1521
+ if ($p_header['comment_len'] != 0)
1522
+ {
1523
+ fputs($tempheader, $p_header['comment'], $p_header['comment_len']);
1524
+ }
1525
+
1526
+ // ----- Return
1527
+ return $v_result;
1528
+ }
1529
+
1530
+ }
1531
+
wpcentral.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: wpcentral
4
+ Plugin URI: https://wpcentral.co
5
+ Description: wpcentral provides a centralized area where you can manage all your WordPress websites singularly, unitedly as well as efficiently.
6
+ Version: 1.0
7
+ Author: Softaculous Ltd.
8
+ Author URI:
9
+ License: GPL2
10
+ License URI:
11
+ Text Domain: wpcentral
12
+ */
13
+ /*
14
+ * This file belongs to the wpcentral plugin.
15
+ *
16
+ * (c) wpcentral LLC <sales@wpcentral.co>
17
+ *
18
+ * You can view the LICENSE file that was distributed with this source code
19
+ * for copywright and license information.
20
+ */
21
+
22
+ if (!defined('ABSPATH')){
23
+ exit;
24
+ }
25
+
26
+ global $wpc_slug;
27
+
28
+ $wpc_slug = 'wp-central/wpcentral.php';
29
+
30
+ include_once(ABSPATH.'wp-admin/includes/plugin.php');
31
+ include_once('wpc_functions.php');
32
+
33
+ add_filter('all_plugins', 'wpc_plugin_info_filter', 10, 1);
34
+ add_filter('all_plugins', 'wpc_plugins_list_filter', 10, 1);
35
+ add_filter('plugin_row_meta', 'wpc_hide_plugin_details', 10, 2);
36
+ add_filter('site_transient_update_plugins', 'wpc_parse_update_plugins', 10, 1);
37
+
38
+ //WPC Activation Hook
39
+ register_activation_hook(__FILE__, 'wpc_activation_hook');
40
+ //WPC De-activation Hook
41
+ register_deactivation_hook(__FILE__, 'wpc_deactivation_hook');
42
+
43
+
44
+ //Add link to show the Connection key once the plugin is activated
45
+ if(is_plugin_active($wpc_slug)){
46
+ add_action('admin_init', 'wpc_enqueue_script');
47
+ add_action('admin_init', 'wpc_enqueue_styles');
48
+ add_filter('plugin_row_meta', 'wpc_add_connection_link', 10, 2);
49
+ add_action('admin_head', 'wpc_modal_open_script');
50
+ add_action('admin_footer', 'wpc_modal_dialog');
51
+
52
+ add_action('admin_notices', 'admin_notice');
53
+
54
+ include_once(ABSPATH.'wp-includes/pluggable.php');
55
+
56
+ add_action('wp_ajax_nopriv_my_wpc_actions', 'my_wpc_actions_init');
57
+
58
+ if(is_user_logged_in()){
59
+ add_action('wp_ajax_my_wpc_signon', 'my_wpc_signon');
60
+ }else{
61
+ add_action('wp_ajax_nopriv_my_wpc_signon', 'my_wpc_signon');
62
+ }
63
+ }
wpcentral_lang.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $l['<title>'] = 'wpcentral';
3
+ $l['unauth_access'] = 'Unauthorized Access!!';
4
+ $l['invalid_auth_key'] = 'Invalid Authorization Key!!';
5
+ $l['no_req_post'] = 'No Request Posted!!';
6
+ $l['copy_fail'] = 'Failed to install the update due to failure in copying some files. This usually occur due to inconsistent file permissions!';
7
+ $l['call_update_fail'] = 'Failed to call the update function!';
8
+ $l['err_activating_pl'] = 'There were some errors while activating the plugin(s).';
9
+ $l['err_deactivating_pl'] = 'There were some errors while deactivating the plugin(s).';
10
+ $l['err_deactivating_del_pl'] = 'There were some errors while deactivating the plugin(s) for deletion.';
11
+ $l['err_deleting_pl'] = 'Plugin(s) deletion failed!';
12
+
13
+ $l['err_activating_theme'] = 'Failed to activate the theme.';
14
+ $l['err_deleting_theme'] = 'Failed to delete the theme.';
15
+
16
+ $l['err_exec'] = 'There was some error executing the function!';
17
+ $l['done'] = 'done';
18
+ $l['func_not_found'] = 'Function does not exist!';
19
+
20
+ $l['invalid_params'] = 'Invalid Parameters!!';
21
+
22
+ $l['err_selectmy'] = 'The MySQL Database could not be selected.';
23
+ $l['err_myconn'] = 'The MySQL Connection could not be established.';
24
+ $l['err_makequery'] = 'Could not make the query numbered';
25
+ $l['err_mynum'] = 'MySQL Error No';
26
+ $l['err_myerr'] = 'MySQL Error';
27
+ $l['err_no_db_file'] = 'The database import file does not exist';
28
+ $l['err_no_open_db_file'] = 'Could not open the database import file';
29
+ $l['err_query'] = 'Could not execute the query';
30
+
31
+ $l['action_failed']='Failed to perform action.';