$name, 'singular_name' => __( 'Note', 'lovely-notes' ), 'menu_name' => '♥ ' . $name, 'name_admin_bar' => __( 'Nouvelle note', 'lovely-notes' ), 'add_new' => __( 'Ajouter', 'lovely-notes' ), 'add_new_item' => __( 'Ajouter une note', 'lovely-notes' ), 'new_item' => __( 'Nouvelle note', 'lovely-notes' ), 'edit_item' => __( 'Modifier la note', 'lovely-notes' ), 'view_item' => __( 'Voir la note', 'lovely-notes' ), 'all_items' => __( 'Toutes les notes', 'lovely-notes' ), 'search_items' => __( 'Rechercher dans le carnet', 'lovely-notes' ), 'not_found' => __( 'Aucune note trouvée.', 'lovely-notes' ), 'not_found_in_trash' => __( 'Aucune note dans la corbeille.', 'lovely-notes' ), 'item_published' => __( 'La note a été publiée.', 'lovely-notes' ), 'item_updated' => __( 'La note a été mise à jour.', 'lovely-notes' ), 'item_reverted_to_draft' => __( 'La note est revenue en brouillon.', 'lovely-notes' ), ); register_post_type( 'lovely_note', array( 'labels' => $labels, 'public' => false, 'show_ui' => true, 'show_in_menu' => true, 'show_in_admin_bar' => true, 'show_in_rest' => true, 'menu_position' => 5, 'menu_icon' => 'dashicons-heart', 'supports' => array( 'editor', 'revisions' ), 'has_archive' => false, 'rewrite' => false, 'query_var' => false, 'exclude_from_search' => true, 'publicly_queryable' => false, 'capability_type' => 'post', 'map_meta_cap' => true, ) ); } /** Load administration assets only where needed. */ public function enqueue_admin_assets( $hook_suffix ) { $screen = get_current_screen(); if ( ! $screen ) { return; } $is_note_screen = 'lovely_note' === $screen->post_type; $is_dashboard = 'index.php' === $hook_suffix; if ( ! $is_note_screen && ! $is_dashboard ) { return; } wp_enqueue_style( 'lovely-notes-admin', LOVELY_NOTES_URL . 'assets/css/admin.css', array(), LOVELY_NOTES_VERSION ); wp_enqueue_media(); wp_enqueue_script( 'lovely-notes-admin', LOVELY_NOTES_URL . 'assets/js/admin.js', array(), LOVELY_NOTES_VERSION, true ); wp_localize_script( 'lovely-notes-admin', 'LovelyNotesAdmin', array( 'frameTitle' => __( 'Choisir un média pour la note', 'lovely-notes' ), 'frameButton' => __( 'Utiliser ce média', 'lovely-notes' ), 'imageLabel' => __( 'Image sélectionnée', 'lovely-notes' ), 'videoLabel' => __( 'Vidéo sélectionnée', 'lovely-notes' ), 'fileLabel' => __( 'Média sélectionné', 'lovely-notes' ), 'copySuccess' => __( 'Code copié !', 'lovely-notes' ), 'copyError' => __( 'Le code est sélectionné. Copiez-le avec le menu de votre navigateur ou le clavier.', 'lovely-notes' ), ) ); } /** Use the native editor placeholder, including when the editor is in an iframe. */ public function editor_settings( $settings, $editor_context ) { if ( isset( $editor_context->post ) && $editor_context->post instanceof WP_Post && 'lovely_note' === $editor_context->post->post_type ) { $settings['bodyPlaceholder'] = $this->editor_placeholder(); } return $settings; } /** Return a translated writing invitation for Lovely Notes only. */ private function editor_placeholder() { $prompts = array( __( 'Le carnet vous écoute…', 'lovely-notes' ), __( 'Une pensée suffit parfois…', 'lovely-notes' ), __( 'Que souhaitez-vous garder aujourd’hui ?', 'lovely-notes' ), __( 'Les petits riens font les grands souvenirs…', 'lovely-notes' ), __( 'Quelques lignes seulement…', 'lovely-notes' ), __( 'Une fleur, une musique, une émotion…', 'lovely-notes' ), __( 'Même les petits riens méritent une place…', 'lovely-notes' ), ); return $prompts[ array_rand( $prompts ) ]; } /** Register the dedicated media box. */ public function register_media_meta_box() { add_meta_box( 'lovely_notes_media', __( 'Média de la note', 'lovely-notes' ), array( $this, 'render_media_meta_box' ), 'lovely_note', 'normal', 'high' ); add_meta_box( 'lovely_notes_lovely_eye', __( 'Lovely Eye — Lien à partager', 'lovely-notes' ), array( $this, 'render_lovely_eye_meta_box' ), 'lovely_note', 'normal', 'high' ); } /** Render media selector fields. */ public function render_media_meta_box( $post ) { $attachment_id = absint( get_post_meta( $post->ID, self::META_ATTACHMENT_ID, true ) ); $external = (string) get_post_meta( $post->ID, self::META_EXTERNAL, true ); wp_nonce_field( 'lovely_notes_save_media', 'lovely_notes_media_nonce' ); $this->render_media_fields( $attachment_id, $external, '' ); } /** Render the optional Lovely Eye link box. */ public function render_lovely_eye_meta_box( $post ) { $url = self::get_lovely_eye_url( $post->ID ); wp_nonce_field( 'lovely_notes_save_lovely_eye', 'lovely_notes_lovely_eye_nonce' ); $this->render_lovely_eye_fields( $url, '' ); } /** Shared media field markup for edit screen and dashboard. */ private function render_media_fields( $attachment_id, $external, $prefix ) { $id_name = $prefix . 'lovely_notes_attachment_id'; $external_name = $prefix . 'lovely_notes_external_media'; $preview = $this->get_admin_media_preview( $attachment_id, $external ); ?>

'' ) ); return $image ? $image : ''; } if ( 0 === strpos( $mime, 'video/' ) && $url ) { return ''; } if ( $url ) { return '' . esc_html( basename( get_attached_file( $attachment_id ) ) ) . ''; } } if ( $external ) { if ( filter_var( $external, FILTER_VALIDATE_URL ) ) { return '' . esc_html( $external ) . ''; } return '
' . esc_html__( 'Code d’intégration enregistré', 'lovely-notes' ) . '
'; } return ''; } /** Save media attached to a note. */ public function save_note_media( $post_id ) { if ( ! isset( $_POST['lovely_notes_media_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['lovely_notes_media_nonce'] ) ), 'lovely_notes_save_media' ) ) { return; } if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; } if ( wp_is_post_revision( $post_id ) || ! current_user_can( 'edit_post', $post_id ) ) { return; } $attachment_id = isset( $_POST['lovely_notes_attachment_id'] ) ? absint( $_POST['lovely_notes_attachment_id'] ) : 0; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitize_external_media() allowlists HTML and HTTP(S) URLs. $external = isset( $_POST['lovely_notes_external_media'] ) && is_string( $_POST['lovely_notes_external_media'] ) ? $this->sanitize_external_media( wp_unslash( $_POST['lovely_notes_external_media'] ) ) : ''; $this->update_media_meta( $post_id, $attachment_id, $external ); } /** Save the optional Lovely Eye link attached to a note. */ public function save_note_lovely_eye( $post_id ) { if ( ! isset( $_POST['lovely_notes_lovely_eye_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['lovely_notes_lovely_eye_nonce'] ) ), 'lovely_notes_save_lovely_eye' ) ) { return; } if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; } if ( wp_is_post_revision( $post_id ) || ! current_user_can( 'edit_post', $post_id ) ) { return; } $url = isset( $_POST['lovely_notes_lovely_eye_url'] ) && is_string( $_POST['lovely_notes_lovely_eye_url'] ) ? $this->sanitize_lovely_eye_url( esc_url_raw( wp_unslash( $_POST['lovely_notes_lovely_eye_url'] ), array( 'http', 'https' ) ) ) : ''; $this->update_lovely_eye_meta( $post_id, $url ); } /** Store or remove media metadata. */ private function update_media_meta( $post_id, $attachment_id, $external ) { if ( $attachment_id && 'attachment' === get_post_type( $attachment_id ) ) { update_post_meta( $post_id, self::META_ATTACHMENT_ID, $attachment_id ); } else { delete_post_meta( $post_id, self::META_ATTACHMENT_ID ); } if ( '' !== $external ) { update_post_meta( $post_id, self::META_EXTERNAL, $external ); } else { delete_post_meta( $post_id, self::META_EXTERNAL ); } } /** Store or remove a Lovely Eye URL. */ private function update_lovely_eye_meta( $post_id, $url ) { if ( '' !== $url ) { update_post_meta( $post_id, self::META_LOVELY_EYE_URL, $url ); } else { delete_post_meta( $post_id, self::META_LOVELY_EYE_URL ); } } /** Sanitize a public HTTP(S) link. */ private function sanitize_lovely_eye_url( $value ) { $value = trim( (string) $value ); if ( '' === $value ) { return ''; } return esc_url_raw( $value, array( 'http', 'https' ) ); } /** Return the saved Lovely Eye URL when it is a valid HTTP(S) link. */ public static function get_lovely_eye_url( $post_id ) { $url = trim( (string) get_post_meta( absint( $post_id ), self::META_LOVELY_EYE_URL, true ) ); if ( '' === $url ) { return ''; } $scheme = strtolower( (string) wp_parse_url( $url, PHP_URL_SCHEME ) ); return in_array( $scheme, array( 'http', 'https' ), true ) ? esc_url_raw( $url, array( 'http', 'https' ) ) : ''; } /** Render the delicate Lovely Eye label and external-link button. */ public static function render_lovely_eye( $post_id ) { $url = self::get_lovely_eye_url( $post_id ); if ( '' === $url ) { return ''; } return sprintf( '
%1$s%3$s
', esc_html__( 'Lovely Eye', 'lovely-notes' ), esc_url( $url ), esc_html__( 'Jeter un œil', 'lovely-notes' ) ); } /** Sanitize either a URL or restricted iframe/embed HTML. */ private function sanitize_external_media( $value ) { $value = trim( (string) $value ); if ( '' === $value ) { return ''; } if ( filter_var( $value, FILTER_VALIDATE_URL ) ) { return esc_url_raw( $value, array( 'http', 'https' ) ); } $allowed = array( 'iframe' => array( 'src' => true, 'title' => true, 'width' => true, 'height' => true, 'frameborder' => true, 'allow' => true, 'allowfullscreen' => true, 'loading' => true, 'referrerpolicy' => true, ), 'video' => array( 'src' => true, 'controls' => true, 'poster' => true, 'preload' => true, ), 'source' => array( 'src' => true, 'type' => true, ), ); return wp_kses( $value, $allowed, array( 'http', 'https' ) ); } /** Register quick-publish box on the main dashboard. */ public function register_dashboard_widget() { if ( ! current_user_can( 'publish_posts' ) ) { return; } /* translators: %s: custom microblog name. */ $title = sprintf( __( '♥ Écrire une note — %s', 'lovely-notes' ), Lovely_Notes_Settings::get_name() ); wp_add_dashboard_widget( 'lovely_notes_quick_publish', $title, array( $this, 'render_dashboard_widget' ) ); } /** Render dashboard quick-publish form. */ public function render_dashboard_widget() { ?>
render_media_fields( 0, '', 'quick_' ); ?>
render_lovely_eye_fields( '', 'quick_' ); ?>
'lovely_note', 'post_status' => 'publish', 'post_content' => $content, ), true ); if ( is_wp_error( $post_id ) ) { wp_safe_redirect( add_query_arg( 'lovely_notes_error', 'save', admin_url() ) ); exit; } $attachment_id = isset( $_POST['quick_lovely_notes_attachment_id'] ) ? absint( $_POST['quick_lovely_notes_attachment_id'] ) : 0; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitize_external_media() allowlists HTML and HTTP(S) URLs. $external = isset( $_POST['quick_lovely_notes_external_media'] ) && is_string( $_POST['quick_lovely_notes_external_media'] ) ? $this->sanitize_external_media( wp_unslash( $_POST['quick_lovely_notes_external_media'] ) ) : ''; $this->update_media_meta( $post_id, $attachment_id, $external ); $lovely_eye_url = isset( $_POST['quick_lovely_notes_lovely_eye_url'] ) && is_string( $_POST['quick_lovely_notes_lovely_eye_url'] ) ? $this->sanitize_lovely_eye_url( esc_url_raw( wp_unslash( $_POST['quick_lovely_notes_lovely_eye_url'] ), array( 'http', 'https' ) ) ) : ''; $this->update_lovely_eye_meta( $post_id, $lovely_eye_url ); wp_safe_redirect( add_query_arg( 'lovely_notes_published', '1', admin_url() ) ); exit; } /** Generate an internal hidden title from the note content. */ public function generate_internal_title( $data, $postarr ) { if ( empty( $data['post_type'] ) || 'lovely_note' !== $data['post_type'] ) { return $data; } $content = trim( wp_strip_all_tags( $data['post_content'] ) ); if ( '' === $content ) { $data['post_title'] = __( 'Note sans texte', 'lovely-notes' ); return $data; } $words = preg_split( '/\s+/', $content ); $title = implode( ' ', array_slice( $words, 0, 9 ) ); if ( count( $words ) > 9 ) { $title .= '…'; } $data['post_title'] = $title; return $data; } /** Friendly publication messages. */ public function custom_updated_messages( $messages ) { $messages['lovely_note'] = array( 0 => '', 1 => __( '🌿 Votre note a bien été enregistrée.', 'lovely-notes' ), 4 => __( '🌸 Votre pensée a été ajoutée au carnet.', 'lovely-notes' ), 6 => __( '✨ Une nouvelle page s’est ajoutée au carnet.', 'lovely-notes' ), 7 => __( 'La note a été enregistrée.', 'lovely-notes' ), 8 => __( 'La note a été proposée.', 'lovely-notes' ), 9 => __( 'La note a été programmée.', 'lovely-notes' ), 10 => __( 'Le brouillon de la note a été mis à jour.', 'lovely-notes' ), ); return $messages; } /** Friendly bulk-action messages. */ public function custom_bulk_messages( $messages, $bulk_counts ) { $messages['lovely_note'] = array( /* translators: %s: number of notes. */ 'updated' => _n( '%s note mise à jour.', '%s notes mises à jour.', $bulk_counts['updated'], 'lovely-notes' ), /* translators: %s: number of notes. */ 'locked' => _n( '%s note non modifiée.', '%s notes non modifiées.', $bulk_counts['locked'], 'lovely-notes' ), /* translators: %s: number of notes. */ 'deleted' => _n( '%s note supprimée.', '%s notes supprimées.', $bulk_counts['deleted'], 'lovely-notes' ), /* translators: %s: number of notes. */ 'trashed' => _n( '%s note placée dans la corbeille.', '%s notes placées dans la corbeille.', $bulk_counts['trashed'], 'lovely-notes' ), /* translators: %s: number of notes. */ 'untrashed' => _n( '%s note restaurée.', '%s notes restaurées.', $bulk_counts['untrashed'], 'lovely-notes' ), ); return $messages; } /** Compatibility title placeholder. */ public function title_placeholder( $placeholder, $post ) { return ( $post && 'lovely_note' === $post->post_type ) ? __( 'Titre créé automatiquement', 'lovely-notes' ) : $placeholder; } /** Simplify admin list columns. */ public function set_admin_columns( $columns ) { return array( 'cb' => isset( $columns['cb'] ) ? $columns['cb'] : '', 'media' => __( 'Média / lien', 'lovely-notes' ), 'content' => __( 'Pensée', 'lovely-notes' ), 'date' => __( 'Date', 'lovely-notes' ), ); } /** Render media thumbnail and note excerpt in list. */ public function render_admin_columns( $column, $post_id ) { if ( 'media' === $column ) { $attachment_id = absint( get_post_meta( $post_id, self::META_ATTACHMENT_ID, true ) ); $external = (string) get_post_meta( $post_id, self::META_EXTERNAL, true ); $lovely_eye = self::get_lovely_eye_url( $post_id ); if ( $attachment_id && 0 === strpos( (string) get_post_mime_type( $attachment_id ), 'image/' ) ) { echo wp_get_attachment_image( $attachment_id, array( 64, 64 ), false, array( 'class' => 'lovely-notes-list-thumb', 'alt' => '' ) ); } elseif ( $attachment_id ) { echo ''; } elseif ( $external ) { echo ''; } elseif ( $lovely_eye ) { echo ''; } else { echo ''; } return; } if ( 'content' !== $column ) { return; } $content = get_post_field( 'post_content', $post_id ); $excerpt = wp_trim_words( wp_strip_all_tags( $content ), 24, '…' ); $edit = get_edit_post_link( $post_id ); if ( $edit ) { echo '' . esc_html( $excerpt ?: __( 'Note sans texte', 'lovely-notes' ) ) . ''; } else { echo esc_html( $excerpt ); } } }