PluginProbe
Noted! / trunk
Noted! vtrunk
2.0.2 2.0.1 trunk 1.0 2.0
noted / includes / PageNotes.php

PageNotes.php in Noted! trunk, at includes/PageNotes.php

156 lines 7.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Noted;
6
7 use WP_Post;
8
9 /**
10 * Classic-editor meta box for post-scoped notes.
11 *
12 * Behaves as the fallback when the block editor is not active. The Gutenberg
13 * equivalent (a PluginSidebar) is registered entirely on the JS side.
14 */
15 final class PageNotes
16 {
17 public function __construct(private Settings $settings) {}
18
19 /**
20 * Register WordPress hooks.
21 */
22 public function register(): void
23 {
24 add_action('add_meta_boxes', [$this, 'registerMetaBox']);
25 }
26
27 /**
28 * Register the meta box for every public post type that isn't a note itself.
29 */
30 public function registerMetaBox(string $postType): void
31 {
32 if (! $this->settings->userCanView()) {
33 return;
34 }
35 if (! $this->settings->bool('enable_page_notes', true)) {
36 return;
37 }
38 if ($postType === PostType::SLUG) {
39 return;
40 }
41 // The PluginSidebar covers this on block-editor screens.
42 if (AdminBar::isBlockEditorScreen()) {
43 return;
44 }
45
46 $obj = get_post_type_object($postType);
47 if (! $obj || ! $obj->public) {
48 return;
49 }
50
51 add_meta_box(
52 'noted_page_notes',
53 __('Notes', 'noted'),
54 [$this, 'renderMetaBox'],
55 $postType,
56 'side',
57 'default'
58 );
59 }
60
61 /**
62 * Render the meta box for a given post.
63 */
64 public function renderMetaBox(WP_Post $post): void
65 {
66 $notes = get_posts([
67 'post_type' => PostType::SLUG,
68 'posts_per_page' => -1,
69 'post_status' => 'publish',
70 'meta_query' => [[
71 'key' => PostType::META_ATTACHED_POST_ID,
72 'value' => $post->ID,
73 ]],
74 ]);
75 $notes = PostType::sortPinnedFirst(PostType::filterRenderable($notes));
76 ?>
77 <div class="noted-metabox" data-post-id="<?php echo esc_attr((string) $post->ID); ?>">
78 <div class="noted-metabox-list">
79 <?php if (empty($notes)) : ?>
80 <p class="noted-empty"><?php esc_html_e('No notes on this post yet.', 'noted'); ?></p>
81 <?php else : ?>
82 <?php foreach ($notes as $note) :
83 $username = (string) get_post_meta($note->ID, PostType::META_USERNAME, true);
84 $timestamp = get_post_meta($note->ID, PostType::META_TIMESTAMP, true);
85 $formatted = $timestamp ? date_i18n(get_option('date_format') . ' · ' . get_option('time_format'), strtotime($timestamp)) : '';
86 $isPinned = PostType::isPinned($note);
87 ?>
88 <?php $markdown = (string) get_post_meta($note->ID, PostType::META_MARKDOWN, true); ?>
89 <article
90 class="noted-card noted-card--collapsible<?php echo $isPinned ? ' is-pinned' : ''; ?>"
91 data-note-id="<?php echo esc_attr((string) $note->ID); ?>"
92 data-markdown="<?php echo esc_attr($markdown); ?>"
93 data-title="<?php echo esc_attr(get_the_title($note)); ?>"
94 >
95 <header class="noted-card__head">
96 <button
97 type="button"
98 id="noted-toggle-<?php echo (int) $note->ID; ?>"
99 class="noted-card__title"
100 aria-expanded="false"
101 aria-controls="noted-collapsible-<?php echo (int) $note->ID; ?>"
102 ><?php echo esc_html(get_the_title($note) ?: __('(untitled)', 'noted')); ?></button>
103 </header>
104 <div
105 class="noted-card__collapsible"
106 id="noted-collapsible-<?php echo (int) $note->ID; ?>"
107 role="region"
108 aria-labelledby="noted-toggle-<?php echo (int) $note->ID; ?>"
109 >
110 <div class="noted-card__body"><?php echo wp_kses_post($note->post_content); ?></div>
111 <div class="noted-card__actions">
112 <button type="button" class="button-link noted-metabox-pin" data-note-id="<?php echo esc_attr((string) $note->ID); ?>" aria-pressed="<?php echo $isPinned ? 'true' : 'false'; ?>">
113 <?php echo $isPinned ? esc_html__('Unpin', 'noted') : esc_html__('Pin', 'noted'); ?>
114 </button>
115 <button type="button" class="button-link noted-metabox-edit" data-note-id="<?php echo esc_attr((string) $note->ID); ?>">
116 <?php esc_html_e('Edit', 'noted'); ?>
117 </button>
118 <button type="button" class="button-link button-link-delete noted-metabox-delete" data-note-id="<?php echo esc_attr((string) $note->ID); ?>">
119 <?php esc_html_e('Delete', 'noted'); ?>
120 </button>
121 </div>
122 <footer class="noted-card__meta">
123 <?php
124 /* translators: 1: WordPress username, 2: Date and time string. */
125 $metaLine = sprintf(__('%1$s · %2$s', 'noted'), $username, $formatted);
126 echo esc_html(trim($metaLine, ' ·'));
127 ?>
128 </footer>
129 </div>
130 </article>
131 <?php endforeach; ?>
132 <?php endif; ?>
133 </div>
134 <div class="noted-metabox-add">
135 <p><input type="text" class="noted-metabox-title widefat" placeholder="<?php esc_attr_e('Title', 'noted'); ?>"></p>
136 <p class="noted-metabox-description-wrap">
137 <label class="screen-reader-text" for="noted-metabox-description-<?php echo (int) $post->ID; ?>"><?php esc_html_e('Description', 'noted'); ?></label>
138 <textarea id="noted-metabox-description-<?php echo (int) $post->ID; ?>" class="noted-metabox-description widefat" rows="4" placeholder="<?php esc_attr_e('Write your note…', 'noted'); ?>"></textarea>
139 <a
140 class="noted-markdown-doc-link noted-metabox-markdown-help"
141 href="<?php echo esc_url($this->settings->markdownDocumentationUrl()); ?>"
142 target="_blank"
143 rel="noopener noreferrer"
144 aria-label="<?php echo esc_attr($this->settings->markdownDocumentationLinkAriaLabel()); ?>"
145 data-tooltip="<?php echo esc_attr($this->settings->markdownDocumentationIconTooltip()); ?>"
146 >
147 <span class="dashicons dashicons-info" aria-hidden="true"></span>
148 </a>
149 </p>
150 <p><button type="button" class="button button-primary noted-metabox-add-btn"><?php esc_html_e('Add Note', 'noted'); ?></button></p>
151 </div>
152 </div>
153 <?php
154 }
155 }
156