Frequently in site maintenance, we encounter plugin issues that recur for extended periods of time, across multiple plugin updates. A common problem will be a bad update or update scheme, sometimes as a consequence of poor or incomplete coding by the plugin vendor, sometimes by the development of conficts that a given vendor or even the WordPress team may be slow to address.

At other times, there might be some aspect of a given plugin implementation that you may wish to note for future reference, yours or others: a Premium plugin that’s used only for transitory convenience or very specific task, a plugin that’s currently under assessment or that’s being temporarily kept on hand for reference. In a multisite environment, it might be helpful to note specific sites where a plugin is activated.

Plugin Annotations - Core Update
Plugin Annotations - Plugins Admin
Plugin Annotations Documentation

The following custom plugin is deployed at an actually existing multisite installation.

<?php
/**
 * Plugin Name: GBES Annotate Plugins
 * Plugin URI: https://ckmswp.com
 * Description: Selectively annotate plugins and optionally disable updates
 * Version: 0.2
 * Author: CK MacLeod
 * Author URI: https://ckmswp.com 
 * @todo update this plugin or create new one that uses do_action( 'core_upgrade_preamble' ); to add notes to upgrade page
 */
function gbes_get_plugins_page_id() {
	
	switch_to_blog( 21 ) ;
	
	$query = new WP_Query(
		array(
			'post_type'              => 'docs',
			'title'                  => 'Plugin Annotations',
			'post_status'            => 'all',
			'posts_per_page'         => 1,
			'no_found_rows'          => true,
			'ignore_sticky_posts'    => true,
			'update_post_term_cache' => false,
			'update_post_meta_cache' => false,
			'orderby'                => 'post_date ID',
			'order'                  => 'ASC',
	) );
 	
	if ( ! empty( $query->post ) ) {
		
		$page_got_by_title = $query->post;
		$page_id = $page_got_by_title->ID ; 
		
	} else {
		
		$page_id = 0 ; 
		
	}
	
	restore_current_blog() ; 
	
	return $page_id ; 
		
}
function gbes_get_acf_repeater_values() {
	
	$rows = array() ; 
	
	//ACF Interface installed at GBES University site 
	switch_to_blog( 21 ) ;
	
	$page_id = gbes_get_plugins_page_id() ; 
	
	if ( function_exists( 'get_field' ) ) {
		$rows = get_field( 'field_693cb71d2bd54', $page_id ) ; //"plugin_handling"
		
	} 
	
	restore_current_blog() ; 
	
	return $rows ; 
	
}
/**
 * Add annotation to row meta
 * @todo figure out how to use  "in_plugin_update_message-{$file}", $plugin_data, $response ) from update.php
 * @param array $plugin_meta elements that appear in a row separated by '|' beneath plugin description
 * @param string $plugin_file plugin-folder/plugin-main-file.php
 */
add_filter( 'plugin_row_meta', 'gbes_customize_plugin', 10, 2 ) ;
function gbes_customize_plugin( $plugin_meta, $plugin_file ) {
	
	$rows = gbes_get_acf_repeater_values() ; 
	
	foreach( $rows as $row ) {
	
		$plugin_note = '<b>DEVELOPER NOTE: </b>' . $row['plugin_note'] ; 
		
		if ( $row['plugin_file'] === $plugin_file ) {
			
			array_push( $plugin_meta, $plugin_note ) ; 
			
		}
		
	}
	
	return $plugin_meta ; 
	
}
/** 
 * Update WordPress Core Updates Page 
 * do_action( "update-core-custom_{$action}" );  // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
 */
add_action( 'core_upgrade_preamble', 'gbes_add_to_core_preamble' ) ;
function gbes_add_to_core_preamble() {
	
	$rows = gbes_get_acf_repeater_values() ; 
	
	foreach ( $rows as $row ) {
		
		$update_core = $row['add_to_core_update'] ;
		if ( $update_core ) {
			
			echo '<div class="notice notice-warning update-prevention-message">
			
			<h4><span style="inline-block; border: 1px solid; border-radius: 3px; padding: 0 6px;">' . $row['plugin_name'] . '</span>: ' . $row['plugin_note'] . '</h4>
			
			</div>' ;
			
		}
		
	}
	
}
/** 
 * Output plugin annotations table displaying plugin names, plugin main files by path, and custom plugin notes 
 * @dependencies ACF and GBES Plugin Annotations
 * @note DataTables library and initialization, custom CSS expected
 */
add_shortcode( 'we-docs-plugin-annotations-table', 'we_docs_plugin_annotations_table_handler' ) ;
function we_docs_plugin_annotations_table_handler() {
	
	$post_id = get_the_ID() ; 
	$rows = get_field( 'plugin_handling', $post_id ) ;
	
	ob_start() ; 
	
	echo '<h3>Last Updated: ' . get_field( 'last_edited', $post_id ) . ' ET </h3>' ; 
	echo '<table id="we-docs-list__table" class="data-table we-docs-list__table plugin-annotations" >' ;
	echo '<thead class="data-table__head">
			<tr class="data-table__heading--row data-table__row">' ;
	echo '<th>Plugin Name</th><th>Plugin Main File Location</th><th>Plugin Note</th><th>Core Update</th>' ;
	echo '</tr></thead>' ; 
	echo '<tbody>' ;
	
	foreach( $rows as $row ) {
		
		$name 	= $row['plugin_name'] ;
		$file 	= $row['plugin_file'] ;
		$note	= $row['plugin_note'] ; 
		$update = $row['add_to_core_update'] ? '<i class="bb-icon-l buddyboss bb-icon-check" aria-hidden="true"></i>' : '' ;
		
		echo '<tr>' ;
		echo '<td>' . $name . '</td>' ; 
		echo '<td>' . $file . '</td>' ; 
		echo '<td>' . $note . '</td>' ;  
		echo '<td>' . $update . '</td>' ;
		echo '</tr>' ; 
		
	}
	echo '</tbody>' ; 
	echo '</table>' ;
	
	return ob_get_clean() ; 
	
}

Related Posts