PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 5.7.0
Defender Security – Malware Scanner, Login Security & Firewall v5.7.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 5.7.0, at src/behavior/scan-item/class-abandoned-result.php

186 lines 5.0 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 return array(
34 'id' => $this->owner->id,
35 'type' => $this->owner->type,
36 'file_name' => $data['name'],
37 'version' => $data['version'],
38 'plugin_url' => $data['url'],
39 'tested_wp' => $data['tested_wp'],
40 'short_desc' => $this->get_short_desc( $this->owner->type ),
41 'deletable' => ! $this->is_active_plugin( $data['slug'] ),
42 'reason_text' => $data['reason_text'],
43 'last_updated' => $data['last_updated'],
44 // Follow consistency with other types. Need for WP-CLI command. Full path = base slug for this item.
45 'full_path' => $data['slug'],
46 );
47 }
48
49 /**
50 * There is not resolve-action for the current scan type.
51 *
52 * @return void
53 */
54 public function resolve() {}
55
56 /**
57 * Ignore the abandoned plugin for the current scan.
58 *
59 * @return array An array with a message indicating successful ignore.
60 */
61 public function ignore(): array {
62 $scan = Scan::get_last();
63 $data = $this->owner->raw_data;
64 $issue_name = '<b>' . $data['name'] . '</b>';
65 $res = $scan->ignore_issue( $this->owner->id );
66 if ( ! $res ) {
67 return array(
68 'type_notice' => 'error',
69 'message' => sprintf(
70 /* translators: %s: Scan issue name. */
71 esc_html__( '%s is already marked as Ignored. It can’t be added to the Ignored list again.', 'defender-security' ),
72 $issue_name
73 ),
74 );
75 }
76
77 return array(
78 'message' => sprintf(
79 /* translators: %s: Scan issue name. */
80 esc_html__( 'You’ve successfully ignored the security issue related to %s.', 'defender-security' ),
81 $issue_name
82 ),
83 );
84 }
85
86 /**
87 * Allow the abandoned plugin for the current scan.
88 *
89 * @return array An array with a message indicating successful restoration.
90 */
91 public function unignore(): array {
92 $scan = Scan::get_last();
93 $scan->unignore_issue( $this->owner->id );
94
95 return array( 'message' => esc_html__( 'The plugin has been successfully restored.', 'defender-security' ) );
96 }
97
98 /**
99 * Remove a plugin at the specified path.
100 *
101 * @param string $path The plugin path.
102 *
103 * @return bool
104 */
105 private function maybe_remove( string $path ): bool {
106 if ( is_dir( $path ) ) {
107 return $this->delete_dir( $path );
108 } else {
109 // Sometimes a plugin consists of one file.
110 wp_delete_file( $path );
111 return true;
112 }
113 }
114
115 /**
116 * Removes a plugin based on the provided data, checking if it is active and has the necessary permissions.
117 *
118 * @param array $data An array containing information about the plugin to be removed.
119 *
120 * @return array An array with the status of the removal process and any related messages.
121 */
122 private function remove_plugin( array $data ): array {
123 $active = $this->is_active_plugin( $data['slug'] );
124 if ( $active ) {
125 return array(
126 'type_notice' => 'error',
127 'message' => esc_html__( 'This plugin cannot be removed because it is active.', 'defender-security' ),
128 );
129 }
130
131 $abs_path = $this->get_abs_plugin_path_by_slug( $data['slug'] );
132 if ( file_exists( $abs_path ) && ! $this->maybe_remove( $abs_path ) ) {
133 return array(
134 'type_notice' => 'error',
135 'message' => esc_html__(
136 'Defender does not have enough permission to remove this plugin.',
137 'defender-security'
138 ),
139 );
140 }
141
142 $message = sprintf(
143 /* translators: %s: Plugin name. */
144 esc_html__( '%s plugin', 'defender-security' ),
145 '<b>' . $data['name'] . '</b>'
146 );
147 $this->log( $message . ' is deleted', Scan_Controller::SCAN_LOG );
148 $model = Scan::get_last();
149 $model->remove_issue( $this->owner->id );
150 // No makes sense to remove related issue(-s) because it's whole folder. Not file.
151
152 do_action( 'wpdef_fixed_scan_issue', 'abandoned_plugin', 'delete' );
153
154 return array(
155 'message' => esc_html__( 'This item has been permanently removed', 'defender-security' ),
156 );
157 }
158
159 /**
160 * Delete whole folder.
161 *
162 * @return array
163 */
164 public function delete(): array {
165 $data = $this->owner->raw_data;
166 return $this->remove_plugin( $data );
167 }
168
169 /**
170 * Get the short description.
171 *
172 * @param string $type Scan type.
173 *
174 * @return string
175 */
176 private function get_short_desc( string $type ): string {
177 return Scan_Item::TYPE_PLUGIN_OUTDATED === $type
178 ? sprintf(
179 /* translators: %s: Time period. */
180 esc_html__( 'No updates released by the author in the past %s', 'defender-security' ),
181 \WP_Defender\Behavior\Scan\Abandoned_Plugin::get_outdated_period()
182 )
183 : esc_html__( 'Removed from the wordpress.org repository', 'defender-security' );
184 }
185 }
186