PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.2.0
Defender Security – Malware Scanner, Login Security & Firewall v6.2.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / src / behavior / scan-item / class-abandoned-result.php

class-abandoned-result.php in Defender Security – Malware Scanner, Login Security & Firewall 6.2.0, at src/behavior/scan-item/class-abandoned-result.php

202 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Handles abandoned plugin scan item.
4 *
5 * @package WP_Defender\Behavior\Scan_Item
6 */
7
8 namespace WP_Defender\Behavior\Scan_Item;
9
10 use WP_Defender\Traits\IO;
11 use WP_Defender\Model\Scan;
12 use WP_Defender\Traits\Plugin;
13 use Calotes\Component\Behavior;
14 use WP_Defender\Model\Scan_Item;
15 use WP_Defender\Controller\Scan as Scan_Controller;
16
17 /**
18 * Class Abandoned_Result.
19 */
20 class Abandoned_Result extends Behavior {
21
22 use IO;
23 use Plugin;
24
25 /**
26 * Return general data so we can output on frontend.
27 *
28 * @return array
29 */
30 public function to_array(): array {
31 $data = $this->owner->raw_data;
32
33 $last_updated = isset( $data['last_updated'] ) ? trim( $data['last_updated'] ) : '';
34 if ( '' !== $last_updated ) {
35 $ttl = strtotime( $last_updated );
36 if ( false !== $ttl ) {
37 $last_updated = wp_date( 'M j, Y', $ttl );
38 }
39 }
40
41 return array(
42 'id' => $this->owner->id,
43 'type' => $this->owner->type,
44 'file_name' => $data['name'],
45 'version' => $data['version'],
46 'plugin_url' => $data['url'],
47 'tested_wp' => $data['tested_wp'],
48 'short_desc' => $this->get_short_desc( $this->owner->type ),
49 'deletable' => ! $this->is_active_plugin( $data['slug'] ),
50 'reason_text' => $data['reason_text'],
51 'last_updated' => $last_updated,
52 // Follow consistency with other types. Need for WP-CLI command. Full path = base slug for this item.
53 'full_path' => $data['slug'],
54 );
55 }
56
57 /**
58 * There is not resolve-action for the current scan type.
59 *
60 * @return void
61 */
62 public function resolve() {}
63
64 /**
65 * Ignore the abandoned plugin for the current scan.
66 *
67 * @return array An array with a message indicating successful ignore.
68 */
69 public function ignore(): array {
70 $scan = Scan::get_last();
71 $issue_name = '<b>' . $this->get_issue_name( $this->owner->raw_data ) . '</b>';
72 $res = $scan->ignore_issue( $this->owner->id );
73 if ( ! $res ) {
74 return array(
75 'type_notice' => 'error',
76 'message' => $this->get_failed_ignore_result( $issue_name ),
77 );
78 }
79
80 return array(
81 'message' => sprintf(
82 /* translators: %s: Scan issue name. */
83 esc_html__( 'You’ve successfully ignored the security issue related to %s.', 'defender-security' ),
84 $issue_name
85 ),
86 );
87 }
88
89 /**
90 * Allow the abandoned plugin for the current scan.
91 *
92 * @return array An array with a message indicating successful restoration.
93 */
94 public function unignore(): array {
95 $scan = Scan::get_last();
96 $issue_name = '<b>' . $this->get_issue_name( $this->owner->raw_data ) . '</b>';
97 $res = $scan->unignore_issue( $this->owner->id );
98 if ( ! $res ) {
99 return array(
100 'type_notice' => 'error',
101 'message' => $this->get_failed_restore_result( $issue_name ),
102 );
103 }
104
105 return array(
106 'message' => sprintf(
107 /* translators: %s: Scan issue name. */
108 esc_html__( 'You’ve successfully restored the security issue related to %s.', 'defender-security' ),
109 $issue_name
110 ),
111 );
112 }
113
114 /**
115 * Remove a plugin at the specified path.
116 *
117 * @param string $path The plugin path.
118 *
119 * @return bool
120 */
121 private function maybe_remove( string $path ): bool {
122 if ( is_dir( $path ) ) {
123 return $this->delete_dir( $path );
124 } else {
125 // Sometimes a plugin consists of one file.
126 wp_delete_file( $path );
127 return true;
128 }
129 }
130
131 /**
132 * Removes a plugin based on the provided data, checking if it is active and has the necessary permissions.
133 *
134 * @param array $data An array containing information about the plugin to be removed.
135 *
136 * @return array An array with the status of the removal process and any related messages.
137 */
138 private function remove_plugin( array $data ): array {
139 $active = $this->is_active_plugin( $data['slug'] );
140 if ( $active ) {
141 return array(
142 'type_notice' => 'error',
143 'message' => esc_html__( 'This plugin cannot be removed because it is active.', 'defender-security' ),
144 );
145 }
146
147 $abs_path = $this->get_abs_plugin_path_by_slug( $data['slug'] );
148 if ( file_exists( $abs_path ) && ! $this->maybe_remove( $abs_path ) ) {
149 return array(
150 'type_notice' => 'error',
151 'message' => esc_html__(
152 'Defender does not have enough permission to remove this plugin.',
153 'defender-security'
154 ),
155 );
156 }
157
158 $message = sprintf(
159 /* translators: %s: Plugin name. */
160 esc_html__( '%s plugin', 'defender-security' ),
161 '<b>' . $data['name'] . '</b>'
162 );
163 $this->log( $message . ' is deleted', Scan_Controller::SCAN_LOG );
164 $model = Scan::get_last();
165 $model->remove_issue( $this->owner->id );
166 // No makes sense to remove related issue(-s) because it's whole folder. Not file.
167
168 do_action( 'wpdef_fixed_scan_issue', 'abandoned_plugin', 'delete' );
169
170 return array(
171 'message' => esc_html__( 'This item has been permanently removed', 'defender-security' ),
172 );
173 }
174
175 /**
176 * Delete whole folder.
177 *
178 * @return array
179 */
180 public function delete(): array {
181 $data = $this->owner->raw_data;
182 return $this->remove_plugin( $data );
183 }
184
185 /**
186 * Get the short description.
187 *
188 * @param string $type Scan type.
189 *
190 * @return string
191 */
192 private function get_short_desc( string $type ): string {
193 return Scan_Item::TYPE_PLUGIN_OUTDATED === $type
194 ? sprintf(
195 /* translators: %s: Time period. */
196 esc_html__( 'No updates released by the author in the past %s', 'defender-security' ),
197 \WP_Defender\Behavior\Scan\Abandoned_Plugin::get_outdated_period()
198 )
199 : esc_html__( 'Removed from the wordpress.org repository', 'defender-security' );
200 }
201 }
202