PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.5
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.5
3.4.5 3.4.4 3.4.3 3.4.2 3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 All 198 releases
← All changes | vendor/convertkit/convertkit-wordpress-libraries/src/class-convertkit-log.php +92 -39 3.3.2 → 3.4.5 View file →
@@ -19,9 +19,9 @@
19 19 * @since 1.4.2
20 20 *
21 21 * @var string
22 22 */
23 - private $path;
23 + private $path = '';
24 24
25 25 /**
26 26 * The path and filename of the log file.
27 27 *
@@ -28,9 +28,9 @@
28 28 * @since 1.0.0
29 29 *
30 30 * @var string
31 31 */
32 - private $log_file;
32 + private $log_file = '';
33 33
34 34 /**
35 35 * Constructor. Defines the log file location.
36 36 *
@@ -39,19 +39,23 @@
39 39 * @param string $path Path to where log file should be created/edited/read.
40 40 */
41 41 public function __construct( $path ) {
42 42
43 - // Define location of log file.
44 - $this->path = trailingslashit( $path . '/log' );
45 - $this->log_file = $this->path . 'log.txt';
43 + // If legacy log files exist in the Plugin's directory, delete them now.
44 + $this->maybe_delete_legacy_log_files( $path );
46 45
47 - // Initialize WP_Filesystem.
48 - require_once ABSPATH . 'wp-admin/includes/file.php';
49 - WP_Filesystem();
46 + // Fetch the uploads directory.
47 + $upload_dir = wp_upload_dir();
50 48
51 - // If a historic log file exists, delete it now.
52 - $this->maybe_delete_historic_log_file( $path );
49 + // Bail if the uploads directory is unavailable.
50 + if ( ! empty( $upload_dir['error'] ) || empty( $upload_dir['basedir'] ) ) {
51 + return;
52 + }
53 53
54 + // Define location of log file.
55 + $this->path = trailingslashit( $upload_dir['basedir'] ) . 'kit-logs/';
56 + $this->log_file = $this->path . $this->get_log_file_name( $path );
57 +
54 58 // If the secure log directory does not exist, create it now.
55 59 $this->maybe_create_secure_log_directory();
56 60
57 61 }
@@ -56,24 +60,41 @@
56 60
57 61 }
58 62
59 63 /**
60 - * Deletes a log.txt file for the given 'old' log file path location,
61 - * which does not have .htaccess or index.html protection.
64 + * Deletes log files stored in the Plugin's directory by earlier versions of
65 + * this class.
62 66 *
67 + * Deletes:
68 + * - `log.txt`, used prior to 1.4.2, which has no .htaccess or index.html protection,
69 + * - `log` directory and its contents, used from 1.4.2 to 2.6.0.
70 + *
63 71 * @since 1.4.2
64 72 *
65 - * @param string $old_path Path to possible historic log file.
73 + * @param string $path Path to the Plugin.
66 74 */
67 - private function maybe_delete_historic_log_file( $old_path ) {
75 + private function maybe_delete_legacy_log_files( $path ) {
68 76
69 - // Bail if file doesn't exist.
70 - if ( ! file_exists( trailingslashit( $old_path ) . 'log.txt' ) ) {
71 - return;
77 + // If a log.txt file exists in the Plugin's directory (i.e. from 1.4.2 or earlier), delete it.
78 + $legacy_file = trailingslashit( $path ) . 'log.txt';
79 + if ( file_exists( $legacy_file ) ) {
80 + wp_delete_file( $legacy_file );
72 81 }
73 82
74 - wp_delete_file( trailingslashit( $old_path ) . 'log.txt' );
83 + // If a log directory exists in the Plugin's directory (i.e. from 1.4.2 to 2.6.0), delete it and its contents.
84 + $legacy_path = trailingslashit( $path ) . 'log';
85 + if ( is_dir( $legacy_path ) ) {
86 + // Delete the files this class created in the log directory.
87 + foreach ( array( 'log.txt', '.htaccess', 'index.html' ) as $file ) {
88 + if ( file_exists( trailingslashit( $legacy_path ) . $file ) ) {
89 + wp_delete_file( trailingslashit( $legacy_path ) . $file );
90 + }
91 + }
75 92
93 + // Delete the log directory.
94 + rmdir( trailingslashit( $path ) . 'log' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_rmdir
95 + }
96 +
76 97 }
77 98
78 99 /**
79 100 * Creates a directory to store the log file, with .htaccess and index.html
@@ -78,21 +99,29 @@
78 99 /**
79 100 * Creates a directory to store the log file, with .htaccess and index.html
80 101 * files to protect the log file, as WooCommerce does.
81 102 *
103 + * Disables logging if the directory could not be created, or isn't writable.
104 + *
82 105 * @since 1.4.2
83 106 */
84 107 private function maybe_create_secure_log_directory() {
85 108
86 - // Initialize WordPress file system.
87 - global $wp_filesystem;
88 -
89 109 // Create directory.
90 110 wp_mkdir_p( $this->path );
91 111
112 + // Disable logging if the directory doesn't exist or isn't writable.
113 + if ( ! is_dir( $this->path ) || ! wp_is_writable( $this->path ) ) {
114 + $this->path = '';
115 + $this->log_file = '';
116 + return;
117 + }
118 +
92 119 // Define files to protect the directory.
93 - $wp_filesystem->put_contents( $this->path . '.htaccess', 'deny from all' );
94 - $wp_filesystem->put_contents( $this->path . 'index.html', '' );
120 + // phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
121 + file_put_contents( $this->path . '.htaccess', 'deny from all' );
122 + file_put_contents( $this->path . 'index.html', '' );
123 + // phpcs:enable WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
95 124
96 125 }
97 126
98 127 /**
@@ -116,8 +145,13 @@
116 145 * @return bool
117 146 */
118 147 public function exists() {
119 148
149 + // Bail if logging is disabled.
150 + if ( ! $this->log_file ) {
151 + return false;
152 + }
153 +
120 154 return file_exists( $this->get_filename() );
121 155
122 156 }
123 157
@@ -129,17 +163,16 @@
129 163 * @param string $entry Log Line Entry.
130 164 */
131 165 public function add( $entry ) {
132 166
133 - // Initialize WordPress file system.
134 - global $wp_filesystem;
167 + // Bail if logging is disabled.
168 + if ( ! $this->log_file ) {
169 + return;
170 + }
135 171
136 172 // Prefix the entry with a date and time.
137 173 $entry = '(' . gmdate( 'Y-m-d H:i:s' ) . ') ' . $entry . "\n";
138 174
139 - // Get any existing log file contents.
140 - $contents = $wp_filesystem->get_contents( $this->get_filename() );
141 -
142 175 // Mask email addresses that may be contained within the entry.
143 176 $entry = preg_replace_callback(
144 177 '^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})^',
145 178 function ( $matches ) {
@@ -148,13 +181,11 @@
148 181 $entry
149 182 );
150 183
151 184 // Append entry.
152 - $contents .= $entry;
185 + // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
186 + file_put_contents( $this->get_filename(), $entry, FILE_APPEND );
153 187
154 - // Write contents.
155 - $wp_filesystem->put_contents( $this->get_filename(), $contents );
156 -
157 188 }
158 189
159 190 /**
160 191 * Reads the given number of lines from the log file.
@@ -165,11 +196,8 @@
165 196 * @return string Log file data
166 197 */
167 198 public function read( $number_of_lines = 500 ) {
168 199
169 - // Initialize WordPress file system.
170 - global $wp_filesystem;
171 -
172 200 // Bail if the log file does not exist.
173 201 if ( ! $this->exists() ) {
174 202 return '';
175 203 }
@@ -174,9 +202,10 @@
174 202 return '';
175 203 }
176 204
177 205 // Open log file.
178 - $log = $wp_filesystem->get_contents_array( $this->get_filename() );
206 + // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file
207 + $log = file( $this->get_filename() );
179 208
180 209 // Bail if the log file is empty.
181 210 if ( ! is_array( $log ) || ! count( $log ) ) {
182 211 return '';
@@ -193,12 +222,15 @@
193 222 * @since 1.0.0
194 223 */
195 224 public function clear() {
196 225
197 - // Initialize WordPress file system.
198 - global $wp_filesystem;
226 + // Bail if logging is disabled.
227 + if ( ! $this->log_file ) {
228 + return;
229 + }
199 230
200 - $wp_filesystem->put_contents( $this->get_filename(), '' );
231 + // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
232 + file_put_contents( $this->get_filename(), '' );
201 233
202 234 }
203 235
204 236 /**
@@ -207,9 +239,30 @@
207 239 * @since 1.0.0
208 240 */
209 241 public function delete() {
210 242
243 + // Bail if logging is disabled.
244 + if ( ! $this->log_file ) {
245 + return;
246 + }
247 +
211 248 wp_delete_file( $this->get_filename() );
249 +
250 + }
251 +
252 + /**
253 + * Returns the log file's name for the Plugin at the given path.
254 + *
255 + * @since 2.6.1
256 + *
257 + * @param string $path Path to the Plugin.
258 + * @return string
259 + */
260 + private function get_log_file_name( $path ) {
261 +
262 + $slug = sanitize_key( basename( untrailingslashit( $path ) ) );
263 +
264 + return $slug . '-' . wp_hash( $slug ) . '.log';
212 265
213 266 }
214 267
215 268 }