Restore to commit 74e578279624c6045ca440a3459ebfa1f8d54191
This commit is contained in:
@@ -0,0 +1,590 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin Handler
|
||||
*
|
||||
* @package PCChangelogManager
|
||||
*/
|
||||
|
||||
// Prevent direct access to the file.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles all admin functionality for the changelog manager.
|
||||
*/
|
||||
class PC_CLM_Admin {
|
||||
|
||||
/**
|
||||
* Instance of the post type class.
|
||||
*
|
||||
* @var PC_CLM_Post_Type
|
||||
*/
|
||||
private $post_type;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param PC_CLM_Post_Type $post_type Post type instance.
|
||||
*/
|
||||
public function __construct( $post_type ) {
|
||||
$this->post_type = $post_type;
|
||||
$this->init_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize admin hooks.
|
||||
*/
|
||||
private function init_hooks() {
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_styles' ) );
|
||||
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
|
||||
add_action( 'save_post_' . $this->post_type->get_post_type_slug(), array( $this, 'save_meta' ), 10, 2 );
|
||||
add_filter( 'manage_' . $this->post_type->get_post_type_slug() . '_posts_columns', array( $this, 'set_custom_columns' ) );
|
||||
add_action( 'manage_' . $this->post_type->get_post_type_slug() . '_posts_custom_column', array( $this, 'render_custom_columns' ), 10, 2 );
|
||||
add_filter( 'post_row_actions', array( $this, 'modify_row_actions' ), 10, 2 );
|
||||
add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
|
||||
add_action( 'parent_file', array( $this, 'highlight_menu' ) );
|
||||
add_action( 'admin_init', array( $this, 'handle_add_new_form' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue admin styles.
|
||||
*/
|
||||
public function enqueue_styles() {
|
||||
$screen = get_current_screen();
|
||||
|
||||
if ( ! $screen ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only enqueue on changelog post type screens.
|
||||
if ( $this->post_type->get_post_type_slug() !== $screen->post_type ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Enqueue admin stylesheet.
|
||||
if ( file_exists( PC_CLM_PLUGIN_DIR . 'admin/css/admin-style.css' ) ) {
|
||||
wp_enqueue_style(
|
||||
'pc-clm-admin-style',
|
||||
PC_CLM_PLUGIN_URL . 'admin/css/admin-style.css',
|
||||
array(),
|
||||
PC_CLM_VERSION
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add admin menu items.
|
||||
*/
|
||||
public function add_admin_menu() {
|
||||
add_menu_page(
|
||||
__( 'Changelog', 'pc-changelog-manager-abc123' ),
|
||||
__( 'Changelog', 'pc-changelog-manager-abc123' ),
|
||||
'manage_options',
|
||||
'pc-clm-view-changelog',
|
||||
array( $this, 'render_view_changelog_page' ),
|
||||
'dashicons-backup',
|
||||
30
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
'pc-clm-view-changelog',
|
||||
__( 'Add New Changelog Entry', 'pc-changelog-manager-abc123' ),
|
||||
__( 'Add New', 'pc-changelog-manager-abc123' ),
|
||||
'manage_options',
|
||||
'pc-clm-add-new',
|
||||
array( $this, 'render_add_new_page' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the main menu page (no-op).
|
||||
* The top-level menu now links directly to the post list to avoid redirects
|
||||
* that may run after headers/styles have already been sent.
|
||||
*/
|
||||
public function render_main_menu_page() {
|
||||
// Intentionally left blank to avoid header() calls after output.
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the view changelog page - displays changelog entries in admin.
|
||||
*/
|
||||
public function render_view_changelog_page() {
|
||||
$post_type = new PC_CLM_Post_Type();
|
||||
$query = $post_type->get_entries();
|
||||
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1 class="wp-heading-inline"><?php esc_html_e( 'View Changelog', 'pc-changelog-manager-abc123' ); ?></h1>
|
||||
<a href="<?php echo esc_url( admin_url( 'post-new.php?post_type=' . $post_type->get_post_type_slug() ) ); ?>" class="page-title-action">
|
||||
<?php esc_html_e( 'Add New Entry', 'pc-changelog-manager-abc123' ); ?>
|
||||
</a>
|
||||
<hr class="wp-header-end">
|
||||
|
||||
<?php if ( $query->have_posts() ) : ?>
|
||||
<div class="pc-clm-admin-view-list">
|
||||
<?php
|
||||
while ( $query->have_posts() ) :
|
||||
$query->the_post();
|
||||
|
||||
$post_id = get_the_ID();
|
||||
$version = $post_type->get_meta( $post_id, 'version_number' );
|
||||
$release_date = $post_type->get_meta( $post_id, 'release_date' );
|
||||
$category = $post_type->get_meta( $post_id, 'category' );
|
||||
$categories = $post_type->get_categories();
|
||||
$category_name = isset( $categories[ $category ] ) ? $categories[ $category ] : $category;
|
||||
?>
|
||||
<div class="pc-clm-admin-entry">
|
||||
<div class="pc-clm-admin-entry-header">
|
||||
<?php if ( $version ) : ?>
|
||||
<span class="pc-clm-admin-version"><?php echo esc_html( $version ); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( $release_date ) : ?>
|
||||
<span class="pc-clm-admin-date"><?php echo esc_html( date_i18n( get_option( 'date_format' ), strtotime( $release_date ) ) ); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( $category ) : ?>
|
||||
<span class="pc-clm-admin-category pc-clm-category-<?php echo esc_attr( $category ); ?>"><?php echo esc_html( $category_name ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<h3 class="pc-clm-admin-entry-title">
|
||||
<a href="<?php echo esc_url( get_edit_post_link( $post_id ) ); ?>">
|
||||
<?php the_title(); ?>
|
||||
</a>
|
||||
</h3>
|
||||
|
||||
<div class="pc-clm-admin-entry-content">
|
||||
<?php echo wp_kses_post( wp_trim_words( get_the_content(), 30, '...' ) ); ?>
|
||||
</div>
|
||||
|
||||
<div class="pc-clm-admin-entry-actions">
|
||||
<a href="<?php echo esc_url( get_edit_post_link( $post_id ) ); ?>" class="button button-small">
|
||||
<?php esc_html_e( 'Edit', 'pc-changelog-manager-abc123' ); ?>
|
||||
</a>
|
||||
<a href="<?php echo esc_url( get_permalink( $post_id ) ); ?>" target="_blank" class="button button-small">
|
||||
<?php esc_html_e( 'View', 'pc-changelog-manager-abc123' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
endwhile;
|
||||
|
||||
wp_reset_postdata();
|
||||
?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="pc-clm-admin-empty">
|
||||
<p>
|
||||
<span class="dashicons dashicons-backup" style="font-size: 48px; width: 48px; height: 48px; display: block; margin: 0 auto 16px; opacity: 0.5;"></span>
|
||||
<?php esc_html_e( 'No changelog entries found.', 'pc-changelog-manager-abc123' ); ?>
|
||||
</p>
|
||||
<a href="<?php echo esc_url( admin_url( 'post-new.php?post_type=' . $post_type->get_post_type_slug() ) ); ?>" class="button button-primary">
|
||||
<?php esc_html_e( 'Add Your First Changelog Entry', 'pc-changelog-manager-abc123' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the add new changelog form submission.
|
||||
*/
|
||||
public function handle_add_new_form() {
|
||||
if ( ! isset( $_POST['pc_clm_add_new_nonce'] ) || ! isset( $_POST['pc_clm_submit_new'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['pc_clm_add_new_nonce'] ) ), 'pc_clm_add_new' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$title = isset( $_POST['pc_clm_title'] ) ? sanitize_text_field( wp_unslash( $_POST['pc_clm_title'] ) ) : '';
|
||||
$content = isset( $_POST['pc_clm_content'] ) ? wp_kses_post( wp_unslash( $_POST['pc_clm_content'] ) ) : '';
|
||||
$version = isset( $_POST['pc_clm_version'] ) ? sanitize_text_field( wp_unslash( $_POST['pc_clm_version'] ) ) : '1.0.0';
|
||||
$release_date = isset( $_POST['pc_clm_release_date'] ) ? sanitize_text_field( wp_unslash( $_POST['pc_clm_release_date'] ) ) : current_time( 'Y-m-d' );
|
||||
$category = isset( $_POST['pc_clm_category'] ) ? sanitize_text_field( wp_unslash( $_POST['pc_clm_category'] ) ) : 'new-features';
|
||||
|
||||
if ( empty( $title ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$post_id = wp_insert_post( array(
|
||||
'post_title' => $title,
|
||||
'post_content' => $content,
|
||||
'post_status' => 'publish',
|
||||
'post_type' => $this->post_type->get_post_type_slug(),
|
||||
) );
|
||||
|
||||
if ( ! is_wp_error( $post_id ) ) {
|
||||
$this->post_type->update_meta( $post_id, 'version_number', $version );
|
||||
$this->post_type->update_meta( $post_id, 'release_date', $release_date );
|
||||
$this->post_type->update_meta( $post_id, 'category', $category );
|
||||
|
||||
add_action( 'admin_notices', function() {
|
||||
echo '<div class="notice notice-success is-dismissible"><p>' . esc_html__( 'Changelog entry added successfully!', 'pc-changelog-manager-abc123' ) . '</p></div>';
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the add new changelog page.
|
||||
*/
|
||||
public function render_add_new_page() {
|
||||
$categories = $this->post_type->get_categories();
|
||||
$default_version = '1.0.0';
|
||||
$default_date = current_time( 'Y-m-d' );
|
||||
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1 class="wp-heading-inline"><?php esc_html_e( 'Add New Changelog Entry', 'pc-changelog-manager-abc123' ); ?></h1>
|
||||
<a href="<?php echo esc_url( admin_url( 'admin.php?page=pc-clm-view-changelog' ) ); ?>" class="page-title-action">
|
||||
<?php esc_html_e( 'View All Entries', 'pc-changelog-manager-abc123' ); ?>
|
||||
</a>
|
||||
<hr class="wp-header-end">
|
||||
|
||||
<div class="pc-clm-admin-add-form">
|
||||
<form method="post" action="">
|
||||
<?php wp_nonce_field( 'pc_clm_add_new', 'pc_clm_add_new_nonce' ); ?>
|
||||
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="pc_clm_title"><?php esc_html_e( 'Title', 'pc-changelog-manager-abc123' ); ?> <span class="required">*</span></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" id="pc_clm_title" name="pc_clm_title" class="regular-text" required>
|
||||
<p class="description"><?php esc_html_e( 'Enter a title for this changelog entry.', 'pc-changelog-manager-abc123' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="pc_clm_version"><?php esc_html_e( 'Version Number', 'pc-changelog-manager-abc123' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" id="pc_clm_version" name="pc_clm_version" value="<?php echo esc_attr( $default_version ); ?>" class="regular-text">
|
||||
<p class="description"><?php esc_html_e( 'The version number (e.g., 1.0.0)', 'pc-changelog-manager-abc123' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="pc_clm_release_date"><?php esc_html_e( 'Release Date', 'pc-changelog-manager-abc123' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="date" id="pc_clm_release_date" name="pc_clm_release_date" value="<?php echo esc_attr( $default_date ); ?>">
|
||||
<p class="description"><?php esc_html_e( 'The release date for this version.', 'pc-changelog-manager-abc123' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="pc_clm_category"><?php esc_html_e( 'Category', 'pc-changelog-manager-abc123' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<select id="pc_clm_category" name="pc_clm_category">
|
||||
<?php foreach ( $categories as $slug => $name ) : ?>
|
||||
<option value="<?php echo esc_attr( $slug ); ?>">
|
||||
<?php echo esc_html( $name ); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<p class="description"><?php esc_html_e( 'The category for this changelog entry.', 'pc-changelog-manager-abc123' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="pc_clm_content"><?php esc_html_e( 'Content', 'pc-changelog-manager-abc123' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<?php
|
||||
wp_editor( '', 'pc_clm_content', array(
|
||||
'media_buttons' => true,
|
||||
'textarea_rows' => 10,
|
||||
'teeny' => false,
|
||||
) );
|
||||
?>
|
||||
<p class="description"><?php esc_html_e( 'Describe the changes in this version.', 'pc-changelog-manager-abc123' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p class="submit">
|
||||
<input type="submit" name="pc_clm_submit_new" class="button button-primary" value="<?php esc_attr_e( 'Add Changelog Entry', 'pc-changelog-manager-abc123' ); ?>">
|
||||
<a href="<?php echo esc_url( admin_url( 'admin.php?page=pc-clm-view-changelog' ) ); ?>" class="button">
|
||||
<?php esc_html_e( 'Cancel', 'pc-changelog-manager-abc123' ); ?>
|
||||
</a>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight the correct menu item.
|
||||
*
|
||||
* @param string $parent_file Parent menu slug.
|
||||
* @return string
|
||||
*/
|
||||
public function highlight_menu( $parent_file ) {
|
||||
global $submenu_file, $current_screen;
|
||||
|
||||
if ( ! isset( $current_screen ) ) {
|
||||
return $parent_file;
|
||||
}
|
||||
|
||||
// Handle our custom view changelog page.
|
||||
if ( isset( $current_screen->base ) && 'pc-clm-view-changelog' === $current_screen->base ) {
|
||||
$parent_file = 'pc-clm-view-changelog';
|
||||
$submenu_file = 'pc-clm-view-changelog';
|
||||
}
|
||||
|
||||
// Handle our custom add new page.
|
||||
if ( isset( $current_screen->base ) && 'pc-clm-add-new' === $current_screen->base ) {
|
||||
$parent_file = 'pc-clm-view-changelog';
|
||||
$submenu_file = 'pc-clm-add-new';
|
||||
}
|
||||
|
||||
return $parent_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add meta boxes to the changelog entry editor.
|
||||
*/
|
||||
public function add_meta_boxes() {
|
||||
add_meta_box(
|
||||
'pc_clm_entry_details',
|
||||
__( 'Entry Details', 'pc-changelog-manager-abc123' ),
|
||||
array( $this, 'render_entry_details_meta_box' ),
|
||||
$this->post_type->get_post_type_slug(),
|
||||
'normal',
|
||||
'high'
|
||||
);
|
||||
|
||||
add_meta_box(
|
||||
'pc_clm_preview',
|
||||
__( 'Preview', 'pc-changelog-manager-abc123' ),
|
||||
array( $this, 'render_preview_meta_box' ),
|
||||
$this->post_type->get_post_type_slug(),
|
||||
'side',
|
||||
'low'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the entry details meta box.
|
||||
*
|
||||
* @param WP_Post $post Current post object.
|
||||
*/
|
||||
public function render_entry_details_meta_box( $post ) {
|
||||
// Add nonce field.
|
||||
wp_nonce_field( 'pc_clm_save_meta', 'pc_clm_meta_nonce' );
|
||||
|
||||
// Get current values.
|
||||
$version_number = $this->post_type->get_meta( $post->ID, 'version_number' );
|
||||
$release_date = $this->post_type->get_meta( $post->ID, 'release_date' );
|
||||
$category = $this->post_type->get_meta( $post->ID, 'category' );
|
||||
$categories = $this->post_type->get_categories();
|
||||
|
||||
// Set default values for new posts.
|
||||
if ( empty( $version_number ) ) {
|
||||
$version_number = '1.0.0';
|
||||
}
|
||||
if ( empty( $release_date ) ) {
|
||||
$release_date = current_time( 'Y-m-d' );
|
||||
}
|
||||
?>
|
||||
<div class="pc-clm-meta-fields">
|
||||
<div class="pc-clm-field-group">
|
||||
<label for="pc_clm_version_number"><?php esc_html_e( 'Version Number', 'pc-changelog-manager-abc123' ); ?></label>
|
||||
<input type="text" id="pc_clm_version_number" name="pc_clm_version_number" value="<?php echo esc_attr( $version_number ); ?>" placeholder="e.g., 1.0.0" />
|
||||
<p class="description"><?php esc_html_e( 'The version number for this changelog entry (e.g., 1.0.0, 2.1.3).', 'pc-changelog-manager-abc123' ); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="pc-clm-field-group">
|
||||
<label for="pc_clm_release_date"><?php esc_html_e( 'Release Date', 'pc-changelog-manager-abc123' ); ?></label>
|
||||
<input type="date" id="pc_clm_release_date" name="pc_clm_release_date" value="<?php echo esc_attr( $release_date ); ?>" />
|
||||
<p class="description"><?php esc_html_e( 'The release date for this version.', 'pc-changelog-manager-abc123' ); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="pc-clm-field-group">
|
||||
<label for="pc_clm_category"><?php esc_html_e( 'Category', 'pc-changelog-manager-abc123' ); ?></label>
|
||||
<select id="pc_clm_category" name="pc_clm_category">
|
||||
<?php foreach ( $categories as $slug => $name ) : ?>
|
||||
<option value="<?php echo esc_attr( $slug ); ?>" <?php selected( $category, $slug ); ?>>
|
||||
<?php echo esc_html( $name ); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<p class="description"><?php esc_html_e( 'The category for this changelog entry.', 'pc-changelog-manager-abc123' ); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the preview meta box.
|
||||
*
|
||||
* @param WP_Post $post Current post object.
|
||||
*/
|
||||
public function render_preview_meta_box( $post ) {
|
||||
$view_page_url = pc_clm_get_changelog_page_url();
|
||||
?>
|
||||
<div class="pc-clm-preview-box">
|
||||
<p><?php esc_html_e( 'View your changelog page to see how entries will appear to visitors.', 'pc-changelog-manager-abc123' ); ?></p>
|
||||
<a href="<?php echo esc_url( $view_page_url ); ?>" target="_blank" class="button button-secondary">
|
||||
<span class="dashicons dashicons-external" style="margin-top: 3px;"></span>
|
||||
<?php esc_html_e( 'View Changelog Page', 'pc-changelog-manager-abc123' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Save meta box data.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @param WP_Post $post Post object.
|
||||
*/
|
||||
public function save_meta( $post_id, $post ) {
|
||||
// Verify nonce.
|
||||
if ( ! isset( $_POST['pc_clm_meta_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['pc_clm_meta_nonce'] ) ), 'pc_clm_save_meta' ) ) {
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
// Check if user has permission.
|
||||
if ( ! current_user_can( 'edit_post', $post_id ) ) {
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
// Check if autosave.
|
||||
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
// Save version number.
|
||||
if ( isset( $_POST['pc_clm_version_number'] ) ) {
|
||||
$this->post_type->update_meta( $post_id, 'version_number', sanitize_text_field( wp_unslash( $_POST['pc_clm_version_number'] ) ) );
|
||||
}
|
||||
|
||||
// Save release date.
|
||||
if ( isset( $_POST['pc_clm_release_date'] ) ) {
|
||||
$this->post_type->update_meta( $post_id, 'release_date', sanitize_text_field( wp_unslash( $_POST['pc_clm_release_date'] ) ) );
|
||||
}
|
||||
|
||||
// Save category.
|
||||
if ( isset( $_POST['pc_clm_category'] ) ) {
|
||||
$allowed_categories = array_keys( $this->post_type->get_categories() );
|
||||
$category = sanitize_text_field( wp_unslash( $_POST['pc_clm_category'] ) );
|
||||
if ( in_array( $category, $allowed_categories, true ) ) {
|
||||
$this->post_type->update_meta( $post_id, 'category', $category );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set custom columns for the admin list view.
|
||||
*
|
||||
* @param array $columns Existing columns.
|
||||
* @return array
|
||||
*/
|
||||
public function set_custom_columns( $columns ) {
|
||||
unset( $columns['date'] );
|
||||
|
||||
$new_columns = array(
|
||||
'version' => __( 'Version', 'pc-changelog-manager-abc123' ),
|
||||
'release_date' => __( 'Release Date', 'pc-changelog-manager-abc123' ),
|
||||
'category' => __( 'Category', 'pc-changelog-manager-abc123' ),
|
||||
'date' => __( 'Date', 'pc-changelog-manager-abc123' ),
|
||||
);
|
||||
|
||||
return array_merge( $columns, $new_columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render custom column content.
|
||||
*
|
||||
* @param string $column Column name.
|
||||
* @param int $post_id Post ID.
|
||||
*/
|
||||
public function render_custom_columns( $column, $post_id ) {
|
||||
switch ( $column ) {
|
||||
case 'version':
|
||||
$version = $this->post_type->get_meta( $post_id, 'version_number' );
|
||||
echo esc_html( $version );
|
||||
break;
|
||||
|
||||
case 'release_date':
|
||||
$release_date = $this->post_type->get_meta( $post_id, 'release_date' );
|
||||
if ( $release_date ) {
|
||||
echo esc_html( date_i18n( get_option( 'date_format' ), strtotime( $release_date ) ) );
|
||||
} else {
|
||||
echo '—';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'category':
|
||||
$category = $this->post_type->get_meta( $post_id, 'category' );
|
||||
$categories = $this->post_type->get_categories();
|
||||
$category_name = isset( $categories[ $category ] ) ? $categories[ $category ] : $category;
|
||||
$category_class = 'pc-clm-category-' . esc_attr( $category );
|
||||
|
||||
echo '<span class="pc-clm-category-badge ' . esc_attr( $category_class ) . '">';
|
||||
echo esc_html( $category_name );
|
||||
echo '</span>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify row actions in the admin list.
|
||||
*
|
||||
* @param array $actions Existing actions.
|
||||
* @param WP_Post $post Post object.
|
||||
* @return array
|
||||
*/
|
||||
public function modify_row_actions( $actions, $post ) {
|
||||
if ( $this->post_type->get_post_type_slug() !== $post->post_type ) {
|
||||
return $actions;
|
||||
}
|
||||
|
||||
// Remove quick edit as it doesn't work well with custom meta.
|
||||
if ( isset( $actions['inline hide-if-no-js'] ) ) {
|
||||
unset( $actions['inline hide-if-no-js'] );
|
||||
}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the changelog page URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function pc_clm_get_changelog_page_url() {
|
||||
// First try to get the custom changelog page.
|
||||
$changelog_page = get_page_by_path( 'changelog' );
|
||||
|
||||
if ( $changelog_page && 'publish' === $changelog_page->post_status ) {
|
||||
return get_permalink( $changelog_page );
|
||||
}
|
||||
|
||||
// Fall back to the post type archive URL.
|
||||
$post_type = get_post_type_object( 'pc_changelog' );
|
||||
if ( $post_type && $post_type->has_archive ) {
|
||||
return get_post_type_archive_link( 'pc_changelog' );
|
||||
}
|
||||
|
||||
// Final fallback to home URL with changelog slug.
|
||||
return home_url( '/changelog/' );
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
/**
|
||||
* Custom Post Type Handler
|
||||
*
|
||||
* @package PCChangelogManager
|
||||
*/
|
||||
|
||||
// Prevent direct access to the file.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles registration and management of the changelog custom post type.
|
||||
*/
|
||||
class PC_CLM_Post_Type {
|
||||
|
||||
/**
|
||||
* Post type slug.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const POST_TYPE_SLUG = 'pc_changelog';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
// Intentionally empty.
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the custom post type.
|
||||
*/
|
||||
public function register() {
|
||||
$labels = array(
|
||||
'name' => _x( 'Changelogs', 'Post type general name', 'pc-changelog-manager-abc123' ),
|
||||
'singular_name' => _x( 'Changelog Entry', 'Post type singular name', 'pc-changelog-manager-abc123' ),
|
||||
'menu_name' => _x( 'Changelogs', 'Admin Menu text', 'pc-changelog-manager-abc123' ),
|
||||
'name_admin_bar' => _x( 'Changelog Entry', 'Add New on Toolbar', 'pc-changelog-manager-abc123' ),
|
||||
'add_new' => __( 'Add New', 'pc-changelog-manager-abc123' ),
|
||||
'add_new_item' => __( 'Add New Changelog Entry', 'pc-changelog-manager-abc123' ),
|
||||
'new_item' => __( 'New Changelog Entry', 'pc-changelog-manager-abc123' ),
|
||||
'edit_item' => __( 'Edit Changelog Entry', 'pc-changelog-manager-abc123' ),
|
||||
'view_item' => __( 'View Changelog Entry', 'pc-changelog-manager-abc123' ),
|
||||
'all_items' => __( 'All Changelog Entries', 'pc-changelog-manager-abc123' ),
|
||||
'search_items' => __( 'Search Changelog Entries', 'pc-changelog-manager-abc123' ),
|
||||
'parent_item_colon' => __( 'Parent Changelog Entries:', 'pc-changelog-manager-abc123' ),
|
||||
'not_found' => __( 'No changelog entries found.', 'pc-changelog-manager-abc123' ),
|
||||
'not_found_in_trash' => __( 'No changelog entries found in Trash.', 'pc-changelog-manager-abc123' ),
|
||||
'featured_image' => _x( 'Changelog Cover Image', 'Overrides the "Featured Image" phrase for this post type.', 'pc-changelog-manager-abc123' ),
|
||||
'set_featured_image' => _x( 'Set cover image', 'Overrides the "Set featured image" phrase.', 'pc-changelog-manager-abc123' ),
|
||||
'remove_featured_image' => _x( 'Remove cover image', 'Overrides the "Remove featured image" phrase.', 'pc-changelog-manager-abc123' ),
|
||||
'use_featured_image' => _x( 'Use as cover image', 'Overrides the "Use as featured image" phrase.', 'pc-changelog-manager-abc123' ),
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'labels' => $labels,
|
||||
'public' => true,
|
||||
'publicly_queryable' => true,
|
||||
'show_ui' => true,
|
||||
'show_in_menu' => false,
|
||||
'query_var' => true,
|
||||
'rewrite' => array( 'slug' => 'changelog-entry' ),
|
||||
'capability_type' => 'post',
|
||||
'map_meta_cap' => true,
|
||||
'has_archive' => false,
|
||||
'hierarchical' => false,
|
||||
'menu_position' => 30,
|
||||
'menu_icon' => 'dashicons-backup',
|
||||
'supports' => array(
|
||||
'title',
|
||||
'editor',
|
||||
'revisions',
|
||||
'author',
|
||||
),
|
||||
'show_in_rest' => true,
|
||||
'rest_base' => 'changelog',
|
||||
);
|
||||
|
||||
register_post_type( self::POST_TYPE_SLUG, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post type slug.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_post_type_slug() {
|
||||
return self::POST_TYPE_SLUG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get changelog entries.
|
||||
*
|
||||
* @param array $args Query arguments.
|
||||
* @return WP_Query
|
||||
*/
|
||||
public function get_entries( $args = array() ) {
|
||||
$defaults = array(
|
||||
'post_type' => self::POST_TYPE_SLUG,
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => -1,
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
);
|
||||
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
return new WP_Query( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single changelog entry.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @return WP_Post|null
|
||||
*/
|
||||
public function get_entry( $post_id ) {
|
||||
$post = get_post( $post_id );
|
||||
|
||||
if ( ! $post || self::POST_TYPE_SLUG !== $post->post_type ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $post;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get categories for changelog entries.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_categories() {
|
||||
return array(
|
||||
'new-features' => __( 'New Features', 'pc-changelog-manager-abc123' ),
|
||||
'bug-fixes' => __( 'Bug Fixes', 'pc-changelog-manager-abc123' ),
|
||||
'improvements' => __( 'Improvements', 'pc-changelog-manager-abc123' ),
|
||||
'security' => __( 'Security', 'pc-changelog-manager-abc123' ),
|
||||
'deprecated' => __( 'Deprecated', 'pc-changelog-manager-abc123' ),
|
||||
'removed' => __( 'Removed', 'pc-changelog-manager-abc123' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get changelog entry meta.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @param string $key Meta key.
|
||||
* @param bool $single Whether to return a single value.
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_meta( $post_id, $key, $single = true ) {
|
||||
return get_post_meta( $post_id, '_pc_clm_' . $key, $single );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set changelog entry meta.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @param string $key Meta key.
|
||||
* @param mixed $value Meta value.
|
||||
* @return bool
|
||||
*/
|
||||
public function update_meta( $post_id, $key, $value ) {
|
||||
return update_post_meta( $post_id, '_pc_clm_' . $key, $value );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,438 @@
|
||||
<?php
|
||||
/**
|
||||
* Public Handler
|
||||
*
|
||||
* @package PCChangelogManager
|
||||
*/
|
||||
|
||||
// Prevent direct access to the file.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles all public-facing functionality for the changelog manager.
|
||||
*/
|
||||
class PC_CLM_Public {
|
||||
|
||||
/**
|
||||
* Instance of the post type class.
|
||||
*
|
||||
* @var PC_CLM_Post_Type
|
||||
*/
|
||||
private $post_type;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param PC_CLM_Post_Type $post_type Post type instance.
|
||||
*/
|
||||
public function __construct( $post_type ) {
|
||||
$this->post_type = $post_type;
|
||||
$this->init_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize public hooks.
|
||||
*/
|
||||
private function init_hooks() {
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_styles' ) );
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
add_filter( 'template_include', array( $this, 'template_loader' ) );
|
||||
add_shortcode( 'changelog', array( $this, 'shortcode_changelog' ) );
|
||||
add_action( 'widgets_init', array( $this, 'register_widgets' ) );
|
||||
add_action( 'wp_ajax_pc_clm_upvote', array( $this, 'handle_upvote' ) );
|
||||
add_action( 'wp_ajax_nopriv_pc_clm_upvote', array( $this, 'handle_upvote' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue public styles.
|
||||
*/
|
||||
public function enqueue_styles() {
|
||||
// Check if we're on the changelog page or if shortcode is used.
|
||||
if ( ! $this->is_changelog_page() && ! $this->is_changelog_single() && ! $this->has_shortcode() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$min_suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
|
||||
if ( file_exists( PC_CLM_PLUGIN_DIR . 'public/css/public-style.css' ) ) {
|
||||
// Enqueue main stylesheet.
|
||||
if ( ! wp_style_is( 'pc-clm-public-style', 'enqueued' ) ) {
|
||||
wp_enqueue_style(
|
||||
'pc-clm-public-style',
|
||||
PC_CLM_PLUGIN_URL . 'public/css/public-style.css',
|
||||
array(),
|
||||
PC_CLM_VERSION
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we're on the changelog page.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_changelog_page() {
|
||||
return is_post_type_archive( $this->post_type->get_post_type_slug() );
|
||||
}
|
||||
|
||||
private function is_changelog_single() {
|
||||
return is_singular( $this->post_type->get_post_type_slug() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the page has the changelog shortcode.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function has_shortcode() {
|
||||
if ( ! is_singular() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$post = get_post();
|
||||
if ( ! $post ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return has_shortcode( $post->post_content, 'changelog' );
|
||||
}
|
||||
|
||||
public function template_loader( $template ) {
|
||||
if ( is_singular( $this->post_type->get_post_type_slug() ) ) {
|
||||
$custom_template = PC_CLM_PLUGIN_DIR . 'public/templates/single-pc_changelog.php';
|
||||
if ( file_exists( $custom_template ) ) {
|
||||
return $custom_template;
|
||||
}
|
||||
}
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changelog shortcode.
|
||||
*
|
||||
* @param array $atts Shortcode attributes.
|
||||
* @return string
|
||||
*/
|
||||
public function shortcode_changelog( $atts ) {
|
||||
$atts = shortcode_atts(
|
||||
array(
|
||||
'limit' => 10,
|
||||
'category' => '',
|
||||
'show_date' => 'yes',
|
||||
'show_title' => 'yes',
|
||||
'order' => 'DESC',
|
||||
),
|
||||
$atts,
|
||||
'changelog'
|
||||
);
|
||||
|
||||
// Enqueue styles for the shortcode output.
|
||||
if ( file_exists( PC_CLM_PLUGIN_DIR . 'public/css/public-style.css' ) ) {
|
||||
wp_enqueue_style( 'pc-clm-public-style', PC_CLM_PLUGIN_URL . 'public/css/public-style.css', array(), PC_CLM_VERSION );
|
||||
}
|
||||
|
||||
// Build query args.
|
||||
$query_args = array(
|
||||
'post_type' => $this->post_type->get_post_type_slug(),
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => intval( $atts['limit'] ),
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC' === $atts['order'] ? 'DESC' : 'ASC',
|
||||
);
|
||||
|
||||
// Filter by category if specified.
|
||||
if ( ! empty( $atts['category'] ) ) {
|
||||
$query_args['meta_query'] = array(
|
||||
array(
|
||||
'key' => '_pc_clm_category',
|
||||
'value' => sanitize_text_field( $atts['category'] ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
$query = new WP_Query( $query_args );
|
||||
|
||||
ob_start();
|
||||
|
||||
if ( $query->have_posts() ) {
|
||||
?>
|
||||
<div class="pc-clm-shortcode-wrapper">
|
||||
<?php if ( 'yes' === $atts['show_title'] ) : ?>
|
||||
<h2 class="pc-clm-shortcode-title"><?php esc_html_e( 'Changelog', 'pc-changelog-manager-abc123' ); ?></h2>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="pc-clm-entries-list">
|
||||
<?php
|
||||
while ( $query->have_posts() ) :
|
||||
$query->the_post();
|
||||
$this->render_entry( get_the_ID(), $atts );
|
||||
endwhile;
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
wp_reset_postdata();
|
||||
} else {
|
||||
?>
|
||||
<div class="pc-clm-no-entries">
|
||||
<p><?php esc_html_e( 'No changelog entries found.', 'pc-changelog-manager-abc123' ); ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a single changelog entry.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @param array $atts Shortcode attributes.
|
||||
*/
|
||||
private function render_entry( $post_id, $atts ) {
|
||||
$version = $this->post_type->get_meta( $post_id, 'version_number' );
|
||||
$release_date = $this->post_type->get_meta( $post_id, 'release_date' );
|
||||
$category = $this->post_type->get_meta( $post_id, 'category' );
|
||||
$categories = $this->post_type->get_categories();
|
||||
$category_name = isset( $categories[ $category ] ) ? $categories[ $category ] : $category;
|
||||
$upvote_count = $this->get_upvote_count( $post_id );
|
||||
$has_voted = $this->has_user_voted( $post_id );
|
||||
|
||||
$entry_classes = array( 'pc-clm-entry' );
|
||||
if ( $category ) {
|
||||
$entry_classes[] = 'pc-clm-category-' . $category;
|
||||
}
|
||||
|
||||
?>
|
||||
<article class="<?php echo esc_attr( implode( ' ', $entry_classes ) ); ?>" id="pc-clm-entry-<?php echo esc_attr( $post_id ); ?>">
|
||||
<div class="pc-clm-entry-inner">
|
||||
<div class="pc-clm-entry-header">
|
||||
<div class="pc-clm-entry-meta">
|
||||
<?php if ( $version ) : ?>
|
||||
<span class="pc-clm-version-badge"><?php echo esc_html( $version ); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( 'yes' === $atts['show_date'] && $release_date ) : ?>
|
||||
<span class="pc-clm-release-date"><?php echo esc_html( date_i18n( get_option( 'date_format' ), strtotime( $release_date ) ) ); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( $category ) : ?>
|
||||
<span class="pc-clm-category-badge pc-clm-category-<?php echo esc_attr( $category ); ?>"><?php echo esc_html( $category_name ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="pc-clm-upvote-section">
|
||||
<button class="pc-clm-upvote-btn <?php echo $has_voted ? 'voted' : ''; ?>"
|
||||
data-post-id="<?php echo esc_attr( $post_id ); ?>"
|
||||
<?php echo $has_voted ? 'disabled' : ''; ?>>
|
||||
<span class="pc-clm-upvote-icon">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M12 2l2.4 7.4h7.6l-6 4.6 2.3 7.4-6.3-4.6-6.3 4.6 2.3-7.4-6-4.6h7.6z"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="pc-clm-upvote-count"><?php echo esc_html( $upvote_count ); ?></span>
|
||||
</button>
|
||||
<span class="pc-clm-upvote-label"><?php echo esc_html( _n( 'upvote', 'upvotes', $upvote_count, 'pc-changelog-manager-abc123' ) ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="pc-clm-entry-title">
|
||||
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
|
||||
</h3>
|
||||
|
||||
<div class="pc-clm-entry-content">
|
||||
<?php the_excerpt(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue public scripts.
|
||||
*/
|
||||
public function enqueue_scripts() {
|
||||
// Check if we're on the changelog page or if shortcode is used.
|
||||
if ( ! $this->is_changelog_page() && ! $this->is_changelog_single() && ! $this->has_shortcode() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$min_suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
|
||||
if ( file_exists( PC_CLM_PLUGIN_DIR . 'public/js/public-script.js' ) ) {
|
||||
wp_enqueue_script(
|
||||
'pc-clm-public-script',
|
||||
PC_CLM_PLUGIN_URL . 'public/js/public-script.js',
|
||||
array( 'jquery' ),
|
||||
PC_CLM_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script(
|
||||
'pc-clm-public-script',
|
||||
'pc_clm_ajax',
|
||||
array(
|
||||
'ajax_url' => admin_url( 'admin-ajax.php' ),
|
||||
'nonce' => wp_create_nonce( 'pc_clm_upvote_nonce' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Handle upvote AJAX request.
|
||||
*/
|
||||
public function handle_upvote() {
|
||||
check_ajax_referer( 'pc_clm_upvote_nonce', 'nonce' );
|
||||
|
||||
if ( ! isset( $_POST['post_id'] ) ) {
|
||||
wp_die( 'Invalid request' );
|
||||
}
|
||||
|
||||
$post_id = intval( $_POST['post_id'] );
|
||||
$ip_address = $_SERVER['REMOTE_ADDR'];
|
||||
$user_id = get_current_user_id();
|
||||
|
||||
// Check if user has already voted (by IP or user ID if logged in)
|
||||
$voted_key = $user_id ? "pc_clm_voted_user_{$user_id}" : "pc_clm_voted_ip_{$ip_address}";
|
||||
$voted_posts = get_transient( $voted_key );
|
||||
|
||||
if ( ! $voted_posts ) {
|
||||
$voted_posts = array();
|
||||
}
|
||||
|
||||
if ( in_array( $post_id, $voted_posts ) ) {
|
||||
wp_send_json_error( array( 'message' => __( 'You have already voted for this entry.', 'pc-changelog-manager-abc123' ) ) );
|
||||
return;
|
||||
}
|
||||
|
||||
// Get current vote count
|
||||
$vote_count = get_post_meta( $post_id, '_pc_clm_upvotes', true ) ?: 0;
|
||||
$new_vote_count = intval( $vote_count ) + 1;
|
||||
|
||||
// Update vote count
|
||||
update_post_meta( $post_id, '_pc_clm_upvotes', $new_vote_count );
|
||||
|
||||
// Mark as voted (expires after 30 days)
|
||||
$voted_posts[] = $post_id;
|
||||
set_transient( $voted_key, $voted_posts, 30 * DAY_IN_SECONDS );
|
||||
|
||||
wp_send_json_success( array(
|
||||
'vote_count' => $new_vote_count,
|
||||
'message' => __( 'Thank you for voting!', 'pc-changelog-manager-abc123' ),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get upvote count for a post.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @return int
|
||||
*/
|
||||
public function get_upvote_count( $post_id ) {
|
||||
$vote_count = get_post_meta( $post_id, '_pc_clm_upvotes', true );
|
||||
return intval( $vote_count );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current user has voted for a post.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @return bool
|
||||
*/
|
||||
public function has_user_voted( $post_id ) {
|
||||
$ip_address = $_SERVER['REMOTE_ADDR'];
|
||||
$user_id = get_current_user_id();
|
||||
|
||||
$voted_key = $user_id ? "pc_clm_voted_user_{$user_id}" : "pc_clm_voted_ip_{$ip_address}";
|
||||
$voted_posts = get_transient( $voted_key );
|
||||
|
||||
if ( ! $voted_posts ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array( $post_id, $voted_posts );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register widgets.
|
||||
*/
|
||||
public function register_widgets() {
|
||||
require_once PC_CLM_PLUGIN_DIR . 'public/widgets/class-changelog-widget.php';
|
||||
register_widget( 'PC_CLM_Widget' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Template function to display changelog entries.
|
||||
*
|
||||
* @param array $args Query arguments.
|
||||
*/
|
||||
function pc_clm_display_changelog( $args = array() ) {
|
||||
$post_type = new PC_CLM_Post_Type();
|
||||
$query = $post_type->get_entries( $args );
|
||||
|
||||
if ( $query->have_posts() ) {
|
||||
?>
|
||||
<div class="pc-clm-entries-list">
|
||||
<?php
|
||||
while ( $query->have_posts() ) :
|
||||
$query->the_post();
|
||||
$post_id = get_the_ID();
|
||||
$version = $post_type->get_meta( $post_id, 'version_number' );
|
||||
$release_date = $post_type->get_meta( $post_id, 'release_date' );
|
||||
$category = $post_type->get_meta( $post_id, 'category' );
|
||||
$categories = $post_type->get_categories();
|
||||
$category_name = isset( $categories[ $category ] ) ? $categories[ $category ] : $category;
|
||||
|
||||
$entry_classes = array( 'pc-clm-entry' );
|
||||
if ( $category ) {
|
||||
$entry_classes[] = 'pc-clm-category-' . $category;
|
||||
}
|
||||
?>
|
||||
<article id="post-<?php the_ID(); ?>" <?php post_class( $entry_classes ); ?>>
|
||||
<div class="pc-clm-entry-inner">
|
||||
<div class="pc-clm-entry-meta">
|
||||
<?php if ( $version ) : ?>
|
||||
<span class="pc-clm-version-badge"><?php echo esc_html( $version ); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( $release_date ) : ?>
|
||||
<span class="pc-clm-release-date"><?php echo esc_html( date_i18n( get_option( 'date_format' ), strtotime( $release_date ) ) ); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( $category ) : ?>
|
||||
<span class="pc-clm-category-badge pc-clm-category-<?php echo esc_attr( $category ); ?>"><?php echo esc_html( $category_name ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<h3 class="pc-clm-entry-title">
|
||||
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
|
||||
</h3>
|
||||
|
||||
<div class="pc-clm-entry-content">
|
||||
<?php the_excerpt(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
<?php
|
||||
endwhile;
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<div class="pc-clm-no-entries">
|
||||
<p><?php esc_html_e( 'No changelog entries found.', 'pc-changelog-manager-abc123' ); ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
wp_reset_postdata();
|
||||
}
|
||||
Reference in New Issue
Block a user