PluginProbe
ReCrawler / 1.1.0
ReCrawler v1.1.0
1.1.0 1.0.2 1.0.1 1.0.0 0.3.4 0.3.3 0.1.1 0.1.2 0.1.2.1 0.1.2.2 0.1.3 0.1.4 0.1.5 0.2.0 0.3.0 0.3.1 0.3.2 trunk 0.1.0 0.1.0.1
recrawler / src / Main.php

Main.php in ReCrawler 1.1.0, at src/Main.php

392 lines 10.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Main class.
4 *
5 * @package Mihdan\ReCrawler
6 */
7
8 namespace Mihdan\ReCrawler;
9
10 use Mihdan\ReCrawler\Logger\Logger;
11 use Mihdan\ReCrawler\Migrations\Migrations;
12 use Mihdan\ReCrawler\Providers\Bing\BingIndexNow;
13 use Mihdan\ReCrawler\Providers\Bing\BingWebmaster;
14 use Mihdan\ReCrawler\Providers\Google\GoogleWebmaster;
15 use Mihdan\ReCrawler\Providers\IndexNow\IndexNow;
16 use Mihdan\ReCrawler\Providers\Seznam\SeznamIndexNow;
17 use Mihdan\ReCrawler\Providers\Naver\NaverIndexNow;
18 use Mihdan\ReCrawler\Providers\BlockAiCrawler;
19 use Mihdan\ReCrawler\Providers\WebSub\WebSub;
20 use Mihdan\ReCrawler\Providers\Yandex\YandexIndexNow;
21 use Mihdan\ReCrawler\Providers\Yandex\YandexWebmaster;
22 use Mihdan\ReCrawler\Views\HelpTab;
23 use Mihdan\ReCrawler\Views\Log_List_Table;
24 use Mihdan\ReCrawler\Views\Settings;
25 use Mihdan\ReCrawler\Views\WPOSA;
26 use WP_Post;
27 use WP_List_Table;
28 use WP_Site;
29 use WP_Query;
30
31 /**
32 * Class Main.
33 */
34 class Main {
35 /**
36 * DIC container.
37 *
38 * @var Container $container
39 */
40 private $container;
41
42 /**
43 * Settings instance.
44 *
45 * @var WPOSA $wposa
46 */
47 private $wposa;
48
49 /**
50 * Logger instance.
51 *
52 * @var Logger
53 */
54 private $logger;
55
56 /**
57 * Constructor.
58 *
59 * @param Container $container Container instnace.
60 */
61 public function __construct( Container $container ) {
62 $this->container = $container;
63 }
64
65 public function init() {
66 $this->load_requirements();
67 $this->setup_hooks();
68
69 do_action( 'recrawler/init', $this );
70 }
71
72 /**
73 * @throws NotFoundExceptionInterface
74 * @throws ContainerExceptionInterface
75 */
76 private function load_requirements() {
77
78 if ( ! function_exists( 'dbDelta' ) ) {
79 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
80 }
81
82 $this->logger = $this->container->make( Logger::class );
83
84 $this->container->set(
85 WPOSA::class,
86 function( Container $c ) {
87 return new WPOSA(
88 Utils::get_plugin_name(),
89 Utils::get_plugin_version(),
90 Utils::get_plugin_slug(),
91 Utils::get_plugin_prefix()
92 );
93 }
94 );
95
96 $this->wposa = $this->container->get( WPOSA::class );
97 $this->wposa->setup_hooks();
98
99 ( $this->container->make( BlockAiCrawler::class ) )->setup_hooks();
100 ( $this->container->make( Hooks::class ) )->setup_hooks();
101
102 ( $this->container->make( HelpTab::class ) )->setup_hooks();
103 ( $this->container->make( Settings::class ) )->setup_hooks();
104 ( $this->container->make( Cron::class ) )->setup_hooks();
105 ( $this->container->make( YandexIndexNow::class ) )->setup_hooks();
106 ( $this->container->make( BingIndexNow::class ) )->setup_hooks();
107 ( $this->container->make( SeznamIndexNow::class ) )->setup_hooks();
108 ( $this->container->make( NaverIndexNow::class ) )->setup_hooks();
109 ( $this->container->make( IndexNow::class ) )->setup_hooks();
110
111 ( $this->container->make( YandexWebmaster::class ) )->setup_hooks();
112 ( $this->container->make( BingWebmaster::class ) )->setup_hooks();
113 ( $this->container->make( GoogleWebmaster::class ) )->setup_hooks();
114 ( $this->container->make( WebSub::class ) )->setup_hooks();
115 ( $this->container->make( Migrations::class ) )->setup_hooks();
116 }
117
118 /**
119 * Setup hooks.
120 */
121 public function setup_hooks(): void {
122 add_filter( 'plugin_action_links', [ $this, 'add_settings_link' ], 10, 2 );
123 add_action( 'admin_menu', [ $this, 'add_log_menu_page' ] );
124 add_filter( 'set_screen_option_logs_per_page', [ $this, 'set_screen_option' ], 10, 3 );
125 add_action( 'admin_init', [ $this, 'maybe_upgrade' ] );
126
127 //add_filter( 'post_row_actions', [ $this, 'post_row_actions' ], 10, 2 );
128 //add_filter( 'page_row_actions', [ $this, 'post_row_actions' ], 10, 2 );
129
130 // Add last update column.
131 if ( $this->wposa->get_option( 'show_last_update_column', 'general', 'on' ) === 'on' ) {
132 foreach ( (array) $this->wposa->get_option( 'post_types', 'general', [] ) as $post_type ) {
133 add_filter( "manage_{$post_type}_posts_columns", [ $this, 'add_last_update_column' ] );
134 add_filter( "manage_edit-{$post_type}_sortable_columns", [ $this, 'add_sorting_by_last_update_column' ] );
135
136 add_action( "manage_{$post_type}_posts_custom_column", [ $this, 'add_last_update_column_content' ], 10, 2 );
137 add_action( 'pre_get_posts', [ $this, 'do_sorting_by_last_update_column' ] );
138 }
139 }
140
141 register_activation_hook( RECRAWLER_FILE, [ $this, 'activate_plugin' ] );
142
143 // Multisite.
144 add_action( 'wp_delete_site', [ $this, 'delete_site_tables' ] );
145 add_action( 'wp_insert_site', [ $this, 'add_site_tables' ] );
146 }
147
148 /**
149 * Delete site tables when deleting a site.
150 *
151 * @param WP_Site $old_site Site ID.
152 * @return void
153 */
154 public function delete_site_tables( WP_Site $old_site ): void {
155 switch_to_blog( $old_site->id );
156 $this->drop_tables();
157 restore_current_blog();
158 }
159
160 /**
161 * Add site tables when creating a site.
162 *
163 * @param WP_Site $new_site Site ID.
164 * @return void
165 */
166 public function add_site_tables( WP_Site $new_site ): void {
167 switch_to_blog( $new_site->id );
168 $this->create_tables();
169 restore_current_blog();
170 }
171
172 public function add_last_update_column( array $columns ): array {
173 $columns['recrawler'] = sprintf(
174 '<span class="dashicons dashicons-share" title="%s"></span>',
175 __( 'ReCrawler: Last Update', 'recrawler' )
176 );
177
178 return $columns;
179 }
180
181 public function add_last_update_column_content( string $column_name, int $post_id ): void {
182 if ( $column_name !== 'recrawler' ) {
183 return;
184 }
185
186 $last_update = (int) get_post_meta( $post_id, Utils::get_plugin_prefix() . '_last_update', true );
187
188 if ( $last_update === 0 ) {
189 return;
190 }
191
192 echo esc_html( date( 'd.m.Y H:i', $last_update ) );
193 }
194
195 public function add_sorting_by_last_update_column( array $columns ): array {
196 $columns['recrawler'] = 'recrawler';
197
198 return $columns;
199 }
200
201 public function do_sorting_by_last_update_column( WP_Query $query ) {
202 if ( ! is_admin() ) {
203 return;
204 }
205
206 if ( $query->get( 'orderby' ) === 'recrawler' ) {
207 $query->set( 'meta_key', Utils::get_plugin_prefix() . '_last_update' );
208 $query->set( 'orderby', 'meta_value_num' );
209 }
210 }
211
212
213 public function post_row_actions( array $actions, WP_Post $post ): array {
214 if ( ! in_array( $post->post_type, (array) $this->wposa->get_option( 'post_types', 'general', [] ), true ) ) {
215 return $actions;
216 }
217
218 if ( ! is_post_publicly_viewable( $post ) ) {
219 return $actions;
220 }
221
222 $actions['recrawler'] = sprintf(
223 '<a title="%s" href="%s">ReCrawler</a>',
224 esc_attr( __( 'Notify the search engine', 'recrawler' ) ),
225 1
226 );
227
228 return $actions;
229 }
230
231 /**
232 * Set screen option.
233 *
234 * @param string $status Status.
235 * @param string $option Option name.
236 * @param string $value Option value.
237 *
238 * @return int
239 */
240 public function set_screen_option( $status, $option, $value ): int {
241 return (int) $value;
242 }
243
244 /**
245 * Fired on plugin activate.
246 */
247 public function activate_plugin( $network_wide ) {
248 global $wpdb;
249
250 if ( is_multisite() && $network_wide ) {
251 $sites = get_sites( [ 'fields' => 'ids' ] );
252 foreach ( $sites as $site_id ) {
253 switch_to_blog( $site_id );
254 $this->create_tables();
255 restore_current_blog();
256 }
257 } else {
258 $this->create_tables();
259 }
260 }
261
262 private function drop_tables() {
263 global $wpdb;
264
265 $sql = "DROP TABLE IF EXISTS {$wpdb->prefix}recrawler_log";
266 $wpdb->query( $sql );
267 }
268
269 private function create_tables( bool $upgrade = false ) {
270 global $wpdb;
271
272 $table_name = $wpdb->prefix . 'recrawler_log';
273 $charset_collate = $wpdb->get_charset_collate();
274
275 if ( $upgrade || $wpdb->get_var( "SHOW TABLES LIKE '{$table_name}'" ) !== $table_name ) {
276 $sql = "CREATE TABLE {$wpdb->prefix}recrawler_log (
277 log_id bigint(20) NOT NULL AUTO_INCREMENT,
278 created_at datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
279 level varchar(255) NOT NULL DEFAULT 'debug',
280 search_engine varchar(255) NOT NULL DEFAULT 'site',
281 direction varchar(255) NOT NULL DEFAULT 'incoming',
282 status_code INT(11) NOT NULL DEFAULT 0,
283 message text NOT NULL,
284 PRIMARY KEY (log_id)
285 ) {$charset_collate};";
286
287 dbDelta($sql);
288
289 Utils::set_db_version( Utils::get_plugin_version() );
290 }
291 }
292
293 public function maybe_upgrade() {
294 $db_version = Utils::get_db_version();
295 $plugin_version = Utils::get_plugin_version();
296
297 if ( version_compare( $db_version, $plugin_version, '<' ) ) {
298 $this->create_tables( true );
299 }
300 }
301
302 /**
303 * Add log menu page for dashboard.
304 */
305 public function add_log_menu_page() {
306
307 if ( ! $this->is_logging_enabled() ) {
308 return;
309 }
310
311 $hook = add_submenu_page(
312 RECRAWLER_SLUG,
313 __( 'Log', 'recrawler' ),
314 __( 'Log', 'recrawler' ),
315 'manage_options',
316 RECRAWLER_SLUG . '-log',
317 [ $this, 'render_log_page' ]
318 );
319
320 // The log lives on its own page, so it joins the tab strip as a link.
321 $this->wposa->add_nav_link(
322 [
323 'page' => RECRAWLER_SLUG . '-log',
324 'title' => __( 'Log', 'recrawler' ),
325 ]
326 );
327
328 add_action(
329 "load-$hook",
330 function () {
331 $GLOBALS[ RECRAWLER_PREFIX . '_log' ] = $this->container->make( Log_List_Table::class );
332 }
333 );
334 }
335
336 /**
337 * Render log menu page for dashboard.
338 */
339 public function render_log_page() {
340 ?>
341 <div class="wrap">
342 <div class="wposa">
343 <?php
344 $this->wposa->show_header();
345 $this->wposa->show_navigation();
346 ?>
347 <div class="metabox-holder">
348 <div class="wposa__group">
349 <h2><?php esc_html_e( 'Log', 'recrawler' ); ?></h2>
350 <form action="<?php echo esc_url( admin_url( 'admin.php?page=' . RECRAWLER_SLUG . '-log' ) ); ?>" method="post">
351 <?php
352 /**
353 * WP_List_table.
354 *
355 * @var WP_List_Table $table
356 */
357 $table = $GLOBALS[ RECRAWLER_PREFIX . '_log' ];
358 $table->display();
359 ?>
360 </form>
361 </div>
362 </div>
363 </div>
364 </div>
365 <?php
366 }
367
368 /**
369 * Add plugin action links
370 *
371 * @param array $actions Default actions.
372 * @param string $plugin_file Plugin file.
373 *
374 * @return array
375 */
376 public function add_settings_link( $actions, $plugin_file ) {
377 if ( Utils::get_plugin_basename() === $plugin_file ) {
378 $actions[] = sprintf(
379 '<a href="%s">%s</a>',
380 admin_url( 'admin.php?page=' . Utils::get_plugin_slug() ),
381 esc_html__( 'Settings', 'recrawler' )
382 );
383 }
384
385 return $actions;
386 }
387
388 private function is_logging_enabled(): bool {
389 return $this->wposa->get_option( 'enable', 'general', 'on' ) === 'on';
390 }
391 }
392