PluginProbe
seQura / trunk
seQura vtrunk
4.3.4 4.3.3 4.3.2 4.3.1 trunk 2.0.0 2.0.10 2.0.11 2.0.12 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 3.0.0 3.0.2 3.0.5 3.0.6 3.0.7 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 4.0.0 All 30 releases
sequra / src / Services / Log / class-log-file.php

class-log-file.php in seQura trunk, at src/Services/Log/class-log-file.php

172 lines 4.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Log File Interface
4 *
5 * @package SeQura/WC
6 * @subpackage SeQura/WC/Services
7 */
8
9 namespace SeQura\WC\Services\Log;
10
11 use Exception;
12 use SeQura\Core\BusinessLogic\Domain\Multistore\StoreContext;
13 use Throwable;
14 use WP_Filesystem_Base;
15
16 /**
17 * Provides methods to perform read and write operations on a log file.
18 */
19 class Log_File implements Interface_Log_File {
20
21 private const MAX_LOG_SIZE = 2 * 1024 * 1024; // 2MB
22
23 /**
24 * The path to the log file.
25 *
26 * @var string
27 */
28 private $log_file_path;
29
30 /**
31 * The store context.
32 *
33 * @var StoreContext
34 */
35 private $store_context;
36
37 /**
38 * Constructor.
39 *
40 * @param string $log_file_path The path to the log file.
41 */
42 public function __construct(
43 $log_file_path,
44 StoreContext $store_context
45 ) {
46 $this->log_file_path = $log_file_path;
47 $this->store_context = $store_context;
48 }
49
50 /**
51 * Append content at the end of the log file.
52 *
53 * @param string $content The content to append.
54 * @throws \Exception If something goes wrong. The exception message will contain the error message.
55 */
56 public function append_content( $content ): void {
57 // WP_Filesystem does not support FILE_APPEND flag, so we need to use file_put_contents.
58 // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.file_ops_file_put_contents
59 file_put_contents( $this->get_log_file_path(), $content, FILE_APPEND );
60 }
61
62 /**
63 * Get the WP Filesystem object.
64 *
65 * @throws \Exception If something goes wrong. The exception message will contain the error message.
66 */
67 private function get_file_system(): WP_Filesystem_Base {
68 global $wp_filesystem;
69 require_once ABSPATH . '/wp-admin/includes/file.php';
70 if ( ! WP_Filesystem() ) {
71 throw new Exception( 'Could not load WP Filesystem.' );
72 }
73 return $wp_filesystem;
74 }
75
76 /**
77 * Get the content of the log file.
78 *
79 * @param string $store_id The store ID.
80 * @throws \Exception If something goes wrong. The exception message will contain the error message.
81 *
82 * @return string[] Each element is a line of the log file.
83 */
84 public function get_content( $store_id ): array {
85 if ( ! $this->setup() ) {
86 throw new Exception( 'Could not setup log file.' );
87 }
88
89 $wp_filesystem = $this->get_file_system();
90 $content = array();
91 $path = $this->get_log_file_path( $store_id );
92 if ( ! $wp_filesystem->exists( $path ) ) {
93 throw new Exception( 'Could not read log file.' );
94 }
95
96 $content = $wp_filesystem->get_contents_array( $path );
97
98 if ( false === $content ) {
99 throw new Exception( 'Could not read log file.' );
100 }
101
102 return $content;
103 }
104
105 /**
106 * Clear the log file.
107 *
108 * @param string $store_id The store ID.
109 * @throws \Exception If something goes wrong. The exception message will contain the error message.
110 */
111 public function clear( $store_id = null ): void {
112 $log_file_path = $this->get_log_file_path( $store_id ?? $this->store_context->getStoreId() );
113 $wp_filesystem = $this->get_file_system();
114 if ( $wp_filesystem->exists( $log_file_path ) && ! $wp_filesystem->delete( $log_file_path, false, 'f' ) ) {
115 throw new Exception( 'Could not clear log file.' );
116 }
117
118 if ( ! $this->setup() ) {
119 throw new Exception( 'Could not setup log file.' );
120 }
121 }
122
123 /**
124 * Make sure the log file exists and is writable.
125 */
126 public function setup(): bool {
127 try {
128 $log_file_path = $this->get_log_file_path();
129 $wp_filesystem = $this->get_file_system();
130
131 if ( ! $wp_filesystem->exists( $log_file_path ) ) {
132 $dir = dirname( $log_file_path );
133 if ( ! $wp_filesystem->is_dir( $dir ) && $wp_filesystem->exists( $dir ) ) {
134 return false;
135 }
136
137 if ( ! $wp_filesystem->exists( $dir ) && ! $wp_filesystem->mkdir( $dir, 0755 ) ) {
138 return false;
139 }
140
141 if ( ! $wp_filesystem->put_contents( $log_file_path, '' ) ) {
142 return false;
143 }
144 }
145
146 if ( ! $wp_filesystem->is_writable( dirname( $log_file_path ) ) ) {
147 return false;
148 }
149
150 // check if log file exceed 2MB and if so, clear it.
151 if ( filesize( $log_file_path ) >= self::MAX_LOG_SIZE ) {
152 $this->clear();
153 return $this->setup();
154 }
155
156 return true;
157 } catch ( Throwable $e ) {
158 return false;
159 }
160 }
161
162 /**
163 * Get the log file path.
164 *
165 * @param string|null $store_id The store ID.
166 */
167 private function get_log_file_path( $store_id = null ): string {
168 $path = $this->log_file_path;
169 return str_replace( '{storeId}', $store_id ?? $this->store_context->getStoreId(), $path );
170 }
171 }
172