PluginProbe
RSFirewall! / trunk
RSFirewall! vtrunk
rsfirewall / models / diff.php

diff.php in RSFirewall! trunk, at models/diff.php

195 lines 5.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package RSFirewall!
4 * @copyright (c) 2018 RSJoomla!
5 * @link https://www.rsjoomla.com
6 * @license GNU General Public License http://www.gnu.org/licenses/gpl-3.0.en.html
7 */
8
9 if ( ! defined( 'WPINC' ) ) {
10 die;
11 }
12
13 class RSFirewall_Model_Diff extends RSFirewall_Model
14 {
15 /**
16 * This is the URL for the github WP repository, from where we download the files
17 */
18 const RAW_URL = 'https://raw.githubusercontent.com/WordPress/WordPress/%s/%s';
19
20 /**
21 * @return bool|string
22 * @since 1.0.0
23 */
24 public function get_hash() {
25 if ( isset( $_POST['hid'] ) ) {
26 return esc_html( $_POST['hid'] );
27 }
28
29 return false;
30 }
31
32 /**
33 * @return bool|string
34 * @since 1.0.0
35 */
36 public function get_file() {
37 if ( isset( $_POST['file'] ) ) {
38 $file = sanitize_text_field($_POST['file']);
39 $pattern = '/^[A-Za-z0-9_-]+[A-Za-z0-9_\.-]*([\\\\\/][A-Za-z0-9_\.-]+[A-Za-z0-9_\.-]*)*$/';
40 if (preg_match( $pattern, (string) $file, $matches ))
41 {
42 $result = (string) $matches[0];
43
44 return $result;
45 }
46 }
47
48 return false;
49 }
50
51 /**
52 * @return string
53 * @since 1.0.0
54 */
55 public function get_local_filename() {
56 $path = realpath(RSFIREWALL_SITE . '/' . $this->get_file());
57 $root = realpath(RSFIREWALL_SITE);
58
59 // Check if the path is valid and within the root directory
60 if ($path === false || strpos($path, $root) !== 0) {
61 throw new Exception(sprintf(__('Invalid file path: %s', 'rsfirewall'), $this->get_file()));
62 }
63
64 return $path;
65 }
66
67 /**
68 * @return string
69 * @since 1.0.0
70 */
71 protected function get_wp_version() {
72 global $wp_version;
73
74 return $wp_version;
75 }
76
77 /**
78 * @return string
79 * @throws Exception
80 * @since 1.0.0
81 */
82 public function get_local_file() {
83 $path = $this->get_local_filename();
84
85 if ( ! file_exists( $path ) ) {
86 throw new Exception( sprintf( esc_html__( 'Couldn\'t find %s .', 'rsfirewall' ), $path ) );
87 }
88
89 if ( ! is_readable( $path ) ) {
90 throw new Exception( sprintf( esc_html__( '%s is not readable.', 'rsfirewall' ), $path ) );
91 }
92
93 if ( ! is_file( $path ) ) {
94 throw new Exception( sprintf( esc_html__( '%s is not a file.', 'rsfirewall' ), $path ) );
95 }
96
97 return file_get_contents( $path );
98 }
99
100 /**
101 * @return string
102 * @since 1.0.0
103 */
104 public function get_remote_filename() {
105 return sprintf( self::RAW_URL, $this->get_wp_version(), $this->get_file() );
106 }
107
108 /**
109 * @return mixed
110 * @throws Exception
111 * @since 1.0.0
112 */
113 public function get_remote_file() {
114 $url = $this->get_remote_filename();
115
116 // Try to connect
117 $response = wp_remote_get( $url );
118
119 // Error in response code
120 if ( $response['response']['code'] != 200 ) {
121 throw new Exception( sprintf( esc_html__( 'RSFirewall! could not connect to the GitHub server: %s - %s.', 'rsfirewall' ), $response['response']['code'], $response['response']['message'] ) );
122 }
123
124 return $response['body'];
125 }
126
127 /**
128 * @param $file
129 * @return array()
130 * @since 1.0.0
131 */
132 public function download_original_file( $file ) {
133 $return = array(
134 'status' => false,
135 'files' => array(
136 'localFile' => $file
137 )
138 );
139
140 if (!$file) {
141 $return['message'] = esc_html__('There is no file to download!', 'rsfirewall');
142 return $return;
143 }
144
145 $return['files']['remoteFile'] = sprintf( self::RAW_URL, $this->get_wp_version(), $return['files']['localFile'] );
146
147 try {
148 $response = wp_remote_get( $return['files']['remoteFile'] );
149 // Error in response code
150 if ( $response['response']['code'] != 200 ) {
151 throw new Exception( sprintf( wp_kses_post(__( 'RSFirewall! could not connect to the GitHub server. Response code: %s; Message: %s', 'rsfirewall' )), $response['response']['code'], $response['response']['message'] ) );
152 }
153
154 WP_Filesystem();
155 global $wp_filesystem, $wpdb, $wp_version;
156
157 // check if the file exists
158 $is_missing = false;
159 if (!file_exists(RSFIREWALL_SITE . '/' . $return['files']['localFile'])) {
160 $is_missing = true;
161 }
162
163 // Rewrite the localfile with the remote file
164 if ( ! $wp_filesystem->put_contents( RSFIREWALL_SITE . '/' . $return['files']['localFile'], $response['body'], FS_CHMOD_FILE ) ) {
165 throw new Exception( esc_html__( 'RSFirewall! could not overwrite the local file.', 'rsfirewall' ) );
166 }
167
168 $table = $wpdb->prefix . 'rsfirewall_hashes';
169
170 $id = $wpdb->get_var("SELECT `id` FROM $table WHERE `file`='".$return['files']['localFile']."' AND (`type`='ignore' OR `type`='".$wp_version."') LIMIT 1");
171
172 if (!is_null($id)) {
173 $wpdb->update(
174 $table,
175 array(
176 'hash' => md5_file(RSFIREWALL_SITE . '/' . $return['files']['localFile']),
177 'date' => current_time('mysql'),
178 ),
179 array(
180 'id' => $id,
181 )
182 );
183 }
184
185
186 $return['status'] = true;
187 $return['message'] = (!$is_missing ? esc_html__( 'File overwritten succesfully.', 'rsfirewall' ) : esc_html__( 'File added succesfully.', 'rsfirewall' ));
188
189 } catch ( Exception $e ) {
190 $return['message'] = $e->getMessage();
191 }
192
193 return $return ;
194 }
195 }