Completed
Branch master (ad2140)
by Stephanie
02:50
created

FrmCreateFile::create_directories()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 9
nc 3
nop 1
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
if ( ! defined( 'ABSPATH' ) ) {
4
	die( 'You are not allowed to call this page directly.' );
5
}
6
7
class FrmCreateFile {
8
9
	public $folder_name;
10
	public $file_name;
11
	public $error_message;
12
	public $uploads;
13
	private $new_file_path;
14
	public $chmod_dir = 0755;
15
	public $chmod_file = 0644;
16
	private $has_permission = false;
17
18
	public function __construct( $atts ) {
19
		$this->folder_name = isset( $atts['folder_name'] ) ? $atts['folder_name'] : '';
20
		$this->file_name = $atts['file_name'];
21
		$this->error_message = isset( $atts['error_message'] ) ? $atts['error_message'] : '';
22
		$this->uploads = wp_upload_dir();
23
		$this->set_new_file_path( $atts );
24
		$this->chmod_dir = defined('FS_CHMOD_DIR') ? FS_CHMOD_DIR : ( fileperms( ABSPATH ) & 0777 | 0755 );
25
		$this->chmod_file = defined('FS_CHMOD_FILE') ? FS_CHMOD_FILE : ( fileperms( ABSPATH . 'index.php' ) & 0777 | 0644 );
26
27
		$this->check_permission();
28
	}
29
30
	/**
31
	 * @since 3.0
32
	 */
33
	private function set_new_file_path( $atts ) {
34
		if ( isset( $atts['new_file_path'] ) ) {
35
			$this->new_file_path = $atts['new_file_path'] . '/' . $this->file_name;
36
		} else {
37
			$this->new_file_path = $this->uploads['basedir'] . '/' . $this->folder_name . '/' . $this->file_name;
38
		}
39
	}
40
41
	public function create_file( $file_content ) {
42
		if ( $this->has_permission ) {
43
			$dirs_exist = true;
44
45
			// Create the directories if need be
46
			$this->create_directories( $dirs_exist );
47
48
			// only write the file if the folders exist
49
			if ( $dirs_exist ) {
50
				global $wp_filesystem;
51
				$wp_filesystem->put_contents( $this->new_file_path, $file_content, $this->chmod_file );
52
			}
53
		}
54
	}
55
56
	/**
57
	 * @since 3.0
58
	 */
59
	public function append_file( $file_content ) {
60
		if ( $this->has_permission ) {
61
62
			if ( file_exists( $this->new_file_path ) ) {
63
64
				$existing_content = $this->get_contents();
65
				$file_content = $existing_content . $file_content;
66
			}
67
68
			$this->create_file( $file_content );
69
		}
70
	}
71
72
	/**
73
	 * Combine an array of files into one
74
	 *
75
	 * @since 3.0
76
	 *
77
	 * @param array $file_names And array of file paths
78
	 */
79
	public function combine_files( $file_names ) {
80
		if ( $this->has_permission ) {
81
			$content = '';
82
			foreach ( $file_names as $file_name ) {
83
				$content .= $this->get_contents( $file_name ) . "\n";
84
			}
85
			$this->create_file( $content );
86
		}
87
	}
88
89
	/**
90
	 * @since 3.0
91
	 */
92
	public function get_file_contents() {
93
		$content = '';
94
95
		if ( $this->has_permission ) {
96
			$content = $this->get_contents();
97
		}
98
99
		return $content;
100
	}
101
102
	/**
103
	 * @since 3.0
104
	 */
105
	private function get_contents( $file = '' ) {
106
		global $wp_filesystem;
107
		if ( empty( $file ) ) {
108
			$file = $this->new_file_path;
109
		}
110
		return $wp_filesystem->get_contents( $file );
111
	}
112
113
	/**
114
	 * @since 3.0
115
	 */
116
	private function check_permission() {
117
		$creds = $this->get_creds();
118
119
		$this->has_permission = true;
120
		if ( empty( $creds ) || ! WP_Filesystem( $creds ) ) {
121
			// initialize the API - any problems and we exit
122
			$this->show_error_message();
123
			$this->has_permission = false;
124
		}
125
	}
126
127
	private function create_directories( &$dirs_exist ) {
128
		global $wp_filesystem;
129
130
		$needed_dirs = $this->get_needed_dirs();
131
		foreach ( $needed_dirs as $_dir ) {
132
			// Only check to see if the Dir exists upon creation failure. Less I/O this way.
133
			if ( $wp_filesystem->mkdir( $_dir, $this->chmod_dir ) ) {
134
				$index_path = $_dir . '/index.php';
135
				$wp_filesystem->put_contents( $index_path, "<?php\n// Silence is golden.\n?>", $this->chmod_file );
136
			} else {
137
				$dirs_exist = $wp_filesystem->is_dir( $_dir );
138
			}
139
		}
140
	}
141
142
	private function get_needed_dirs() {
143
		$dir_names = explode( '/', $this->folder_name );
144
		$needed_dirs = array();
145
146
		$next_dir = '';
147
		foreach ( $dir_names as $dir ) {
148
			$next_dir .= '/' . $dir;
149
			$needed_dirs[] = $this->uploads['basedir'] . $next_dir;
150
		}
151
152
		return $needed_dirs;
153
	}
154
155
	private function get_creds() {
156
		if ( ! function_exists('get_filesystem_method') ) {
157
			include_once( ABSPATH . 'wp-admin/includes/file.php' );
158
		}
159
160
		$access_type = get_filesystem_method();
161
		if ( $access_type === 'direct' ) {
162
			$creds = request_filesystem_credentials( site_url() . '/wp-admin/', '', false, false, array() );
163
		} else {
164
			$creds = $this->get_ftp_creds( $access_type );
165
		}
166
		return $creds;
167
	}
168
169
	private function get_ftp_creds( $type ) {
170
		$credentials = get_option( 'ftp_credentials', array(
171
			'hostname' => '',
172
			'username' => '',
173
		) );
174
175
		$credentials['hostname'] = defined('FTP_HOST') ? FTP_HOST : $credentials['hostname'];
176
		$credentials['username'] = defined('FTP_USER') ? FTP_USER : $credentials['username'];
177
		$credentials['password'] = defined('FTP_PASS') ? FTP_PASS : '';
178
179
		// Check to see if we are setting the public/private keys for ssh
180
		$credentials['public_key'] = defined('FTP_PUBKEY') ? FTP_PUBKEY : '';
181
		$credentials['private_key'] = defined('FTP_PRIKEY') ? FTP_PRIKEY : '';
182
183
		// Sanitize the hostname, Some people might pass in odd-data:
184
		$credentials['hostname'] = preg_replace( '|\w+://|', '', $credentials['hostname'] ); //Strip any schemes off
185
186
		if ( strpos( $credentials['hostname'], ':' ) ) {
187
			list( $credentials['hostname'], $credentials['port'] ) = explode( ':', $credentials['hostname'], 2 );
188
			if ( ! is_numeric( $credentials['port'] ) ) {
189
				unset( $credentials['port'] );
190
			}
191
		} else {
192
			unset( $credentials['port'] );
193
		}
194
195
		if ( ( defined( 'FTP_SSH' ) && FTP_SSH ) || ( defined( 'FS_METHOD' ) && 'ssh2' == FS_METHOD ) ) {
196
			$credentials['connection_type'] = 'ssh';
197
		} else if ( ( defined( 'FTP_SSL' ) && FTP_SSL ) && 'ftpext' == $type ) {
198
			//Only the FTP Extension understands SSL
199
			$credentials['connection_type'] = 'ftps';
200
		} else if ( ! isset( $credentials['connection_type'] ) ) {
201
			//All else fails (And it's not defaulted to something else saved), Default to FTP
202
			$credentials['connection_type'] = 'ftp';
203
		}
204
205
		$has_creds = ( ! empty( $credentials['password'] ) && ! empty( $credentials['username'] ) && ! empty( $credentials['hostname'] ) );
206
		$can_ssh = ( 'ssh' == $credentials['connection_type'] && ! empty( $credentials['public_key'] ) && ! empty( $credentials['private_key'] ) );
207
		if ( $has_creds || $can_ssh ) {
208
			$stored_credentials = $credentials;
209
			if ( ! empty( $stored_credentials['port'] ) ) {
210
				//save port as part of hostname to simplify above code.
211
				$stored_credentials['hostname'] .= ':' . $stored_credentials['port'];
212
			}
213
214
			unset( $stored_credentials['password'], $stored_credentials['port'], $stored_credentials['private_key'], $stored_credentials['public_key'] );
215
216
			return $credentials;
217
		}
218
219
		return false;
220
	}
221
222
	private function show_error_message() {
223
		if ( ! empty( $this->error_message ) ) {
224
			echo '<div class="message">' . $this->error_message . '</div>';
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
225
		}
226
	}
227
}
228