'ansico', 'title' => __( 'Ansico Blocks', 'ansico-some-plugin' ), 'icon' => null, ) ); return $categories; } function ansico_get_micropost_max_chars() { $value = get_option( 'ansico_micropost_max_chars', 500 ); $value = intval( $value ); return $value > 0 ? $value : 500; } add_action( 'admin_menu', 'ansico_register_settings_page' ); function ansico_register_settings_page() { add_options_page( 'Ansico SoMe Plugin', 'Ansico SoMe Plugin', 'manage_options', 'ansico-some-plugin-settings', 'ansico_render_settings_page' ); } add_action( 'admin_init', 'ansico_register_settings' ); function ansico_register_settings() { register_setting( 'ansico_some_plugin_settings', 'ansico_micropost_max_chars', array( 'type' => 'integer', 'sanitize_callback' => 'ansico_sanitize_micropost_max_chars', 'default' => 500, ) ); register_setting( 'ansico_some_plugin_settings', 'ansico_clean_up_profile_settings', array( 'type' => 'boolean', 'sanitize_callback' => 'ansico_sanitize_checkbox_setting', 'default' => false, ) ); add_settings_section( 'ansico_some_plugin_main', __( 'Micropost settings', 'ansico-some-plugin' ), function() { echo '

' . esc_html__( 'Settings for Ansico SoMe Plugin.', 'ansico-some-plugin' ) . '

'; }, 'ansico-some-plugin-settings' ); add_settings_field( 'ansico_micropost_max_chars', __( 'Maximum characters in Micropost Form', 'ansico-some-plugin' ), 'ansico_render_micropost_max_chars_field', 'ansico-some-plugin-settings', 'ansico_some_plugin_main' ); add_settings_field( 'ansico_clean_up_profile_settings', __( 'Clean up profile settings', 'ansico-some-plugin' ), 'ansico_render_clean_up_profile_settings_field', 'ansico-some-plugin-settings', 'ansico_some_plugin_main' ); } function ansico_sanitize_checkbox_setting( $value ) { return ! empty( $value ) ? '1' : ''; } function ansico_sanitize_micropost_max_chars( $value ) { $value = intval( $value ); if ( $value < 1 ) { $value = 500; } return $value; } function ansico_render_micropost_max_chars_field() { $value = ansico_get_micropost_max_chars(); echo ''; echo '

' . esc_html__( 'Default is 500 characters.', 'ansico-some-plugin' ) . '

'; } function ansico_render_clean_up_profile_settings_field() { $enabled = ! empty( get_option( 'ansico_clean_up_profile_settings', '' ) ); echo ''; } function ansico_render_settings_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } ?>

is_main_query() && $query->is_author() ) { $types = $query->get('post_type'); if (empty($types) || $types === 'post') { $query->set( 'post_type', array( 'post', 'micropost' ) ); } elseif (is_array($types) && !in_array('micropost', $types)) { $types[] = 'micropost'; $query->set('post_type', $types); } } } /* ========================================================================== 1.6. FORCE COMMENTS OPEN FOR MICROPOSTS ========================================================================== */ add_filter( 'comments_open', 'ansico_force_micropost_comments_open', 10, 2 ); function ansico_force_micropost_comments_open( $open, $post_id ) { if ( get_post_type( $post_id ) === 'micropost' ) { return true; } return $open; } /* ========================================================================== 1.7. FORMAT MICROPOST COMMENTS (Mastodon & Embeds) ========================================================================== */ add_filter( 'comment_text', 'ansico_format_comment_text', 10, 2 ); function ansico_format_comment_text( $text, $comment = null ) { if ( ! is_object( $comment ) || get_post_type( $comment->comment_post_ID ) !== 'micropost' ) { return $text; } return ansico_get_formatted_comment_html( $comment, true ); } function ansico_apply_micropost_text_formatting( $text ) { $text = (string) $text; $text = preg_replace('/\[([^\]]+)\]\((https?:\/\/[^)]+)\)/i', '$1', $text); $text = preg_replace('/(?@$1@$2', $text); $text = preg_replace_callback('/(?<=^|\s|>|>)#([\p{L}\p{N}_]+)/u', function($m) { $link = get_term_link($m[1], 'micropost_tag'); if ( is_wp_error($link) ) { $link = home_url('/micropost-tag/' . sanitize_title($m[1]) . '/'); } return '#' . esc_html($m[1]) . ''; }, $text); $text = make_clickable($text); $text = preg_replace('/\*\*(.+?)\*\*/s', '$1', $text); $text = preg_replace('/\*([^\*]+)\*/s', '$1', $text); $text = preg_replace('/`([^`]+)`/s', '$1', $text); $text = preg_replace('/^>\s+(.*)/m', '
$1
', $text); return $text; } function ansico_get_formatted_comment_html( $comment, $already_filtered = false ) { if ( ! is_object( $comment ) ) { return ''; } $raw_text = isset( $comment->comment_content ) ? (string) $comment->comment_content : ''; if ( $raw_text === '' ) { return ''; } preg_match( '/(https?:\/\/[^\s()<>{}\[\]]+)/i', $raw_text, $url_matches ); $first_url = ! empty( $url_matches[1] ) ? $url_matches[1] : ''; $text = esc_html( $raw_text ); $text = ansico_apply_micropost_text_formatting( $text ); $text = wpautop( $text ); if ( $first_url ) { $embed_data = ansico_fetch_metadata_internal( $first_url ); if ( $embed_data && ! empty( $embed_data['title'] ) ) { $img_html = ! empty( $embed_data['image'] ) ? '' : ''; $text .= '
' . $img_html . '
' . esc_html( $embed_data['domain'] ) . '

' . esc_html( $embed_data['title'] ) . '

'; } } return ansico_prepare_comment_display_html( $text ); } function ansico_prepare_comment_display_html( $html ) { $html = (string) $html; if ( $html === '' ) { return ''; } // Normaliser WordPress-kommentar HTML uden at skabe ekstra luft omkring embeds. $html = shortcode_unautop( $html ); // Fjern tomme afsnit og linjeskift rundt om embed-kort. $patterns = array( '#

\s*(

]*>)#i', '#(
)\s*

#i', '#

\s*(]*>\s*]*class="ansico-tweet-embed-image"[^>]*>\s*)\s*

#i', '#

\s*(]*class="ansico-tweet-embed-image"[^>]*>)\s*

#i', '#

\s*(]*>.*?)\s*

#is', '#

\s*

#i', ); $replacements = array('$1', '$1', '$1', '$1', '$1', ''); $html = preg_replace( $patterns, $replacements, $html ); return trim( $html ); } /* ========================================================================== 1.8. CUSTOM COMMENT MARKUP (Design uden "siger" og med ny opstilling) ========================================================================== */ function ansico_custom_comment_markup($comment, $args, $depth) { $GLOBALS['comment'] = $comment; $avatar = get_avatar($comment, 40, '', '', array('class' => 'ansico-tweet-avatar')); $author_link = get_comment_author_link($comment); $author_url = ''; if ( is_object( $comment ) && ! empty( $comment->user_id ) ) { $author_url = get_author_posts_url( (int) $comment->user_id ); } elseif ( is_object( $comment ) && ! empty( $comment->comment_author_url ) ) { $author_url = $comment->comment_author_url; } $avatar_html = $author_url ? '' . $avatar . '' : $avatar; $time_display = get_comment_date( get_option('date_format'), $comment ) . ' · ' . get_comment_time( get_option('time_format'), false, false, $comment ); $like_button = ansico_render_like_button( 'comment', $comment->comment_ID ); ?>
  • id="comment-" style="position: relative; display: block !important; list-style: none; margin-bottom: 20px;">
    '; comment_reply_link(array_merge($args, array( 'depth' => $depth, 'max_depth' => $args['max_depth'], 'reply_text' => $reply_icon ))); ?>
    array( 'name' => 'Microposts', 'singular_name' => 'Micropost', ), 'public' => true, 'has_archive' => true, 'supports' => array( 'editor', 'author', 'custom-fields', 'comments' ), 'menu_icon' => 'dashicons-edit-page', 'show_in_rest' => true, 'rewrite' => array('slug' => 'micropost'), )); register_taxonomy( 'micropost_tag', 'micropost', array( 'labels' => array( 'name' => 'Tags', 'singular_name' => 'Tag', ), 'public' => true, 'rewrite' => array( 'slug' => 'micropost-tag' ), 'hierarchical' => false, 'show_in_rest' => true, 'show_admin_column' => true, )); } add_filter( 'wp_insert_post_data', function( $data, $postarr ) { if ( $data['post_type'] === 'micropost' && $data['post_status'] !== 'trash' ) { if ( empty( $postarr['post_title'] ) || $postarr['post_title'] === 'Auto Draft' || $postarr['post_title'] === '' ) { $clean_content = strip_tags( $data['post_content'] ); $data['post_title'] = mb_substr( $clean_content, 0, 50 ); } if ( empty( $data['post_name'] ) ) { $data['post_name'] = date('YmdHis') . rand(100, 999); } } return $data; }, 10, 2 ); add_action('save_post_micropost', function($post_id, $post, $update) { if ( wp_is_post_revision( $post_id ) ) return; preg_match_all('/#([\p{L}\p{N}_]+)/u', $post->post_content, $matches); if (!empty($matches[1])) { wp_set_object_terms( $post_id, $matches[1], 'micropost_tag', false ); } }, 10, 3); /* ========================================================================== 2. TEMPLATE STYRING ========================================================================== */ function ansico_get_micropost_ids_matching_search( $search_query ) { global $wpdb; $search_query = trim( (string) $search_query ); if ( $search_query === '' ) { return array(); } $like = '%' . $wpdb->esc_like( $search_query ) . '%'; $post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_status = 'publish' AND (post_title LIKE %s OR post_content LIKE %s)", 'micropost', $like, $like ) ); $comment_post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT c.comment_post_ID FROM {$wpdb->comments} c INNER JOIN {$wpdb->posts} p ON p.ID = c.comment_post_ID WHERE p.post_type = %s AND p.post_status = 'publish' AND c.comment_approved = '1' AND (c.comment_type = '' OR c.comment_type = 'comment') AND c.comment_content LIKE %s", 'micropost', $like ) ); $all_ids = array_unique( array_map( 'intval', array_merge( $post_ids, $comment_post_ids ) ) ); rsort( $all_ids ); return $all_ids; } add_action( 'pre_get_posts', 'ansico_apply_micropost_archive_search' ); function ansico_apply_micropost_archive_search( $query ) { if ( is_admin() || ! $query->is_main_query() ) { return; } if ( $query->is_post_type_archive( 'micropost' ) ) { $search_query = ''; if ( isset( $_GET['ms'] ) ) { $search_query = sanitize_text_field( wp_unslash( $_GET['ms'] ) ); } elseif ( isset( $_GET['s'] ) ) { $search_query = sanitize_text_field( wp_unslash( $_GET['s'] ) ); } if ( $search_query !== '' ) { $matching_ids = ansico_get_micropost_ids_matching_search( $search_query ); $query->set( 'post_type', 'micropost' ); $query->set( 's', '' ); $query->set( 'post__in', ! empty( $matching_ids ) ? $matching_ids : array( 0 ) ); $query->set( 'orderby', 'date' ); $query->set( 'order', 'DESC' ); } } } add_filter('template_include', 'ansico_micropost_templates'); function ansico_micropost_templates( $template ) { // Deaktiveret for enkelte microposts, så din Site Editor skabelon kan bruges. /* if ( is_singular('micropost') ) { $plugin_template = plugin_dir_path(__FILE__) . 'templates/single-micropost.php'; if ( file_exists($plugin_template) ) return $plugin_template; } */ // Brug kun pluginets simple archive-template på det normale micropost-arkiv. // Ved søgning skal temaets eget layout bruges, så sidebar og globalt site-design bevares. if ( is_post_type_archive('micropost') ) { $has_search = false; if ( isset( $_GET['ms'] ) ) { $has_search = trim( (string) wp_unslash( $_GET['ms'] ) ) !== ''; } elseif ( isset( $_GET['s'] ) ) { $has_search = trim( (string) wp_unslash( $_GET['s'] ) ) !== ''; } if ( ! $has_search ) { $plugin_template = plugin_dir_path(__FILE__) . 'templates/archive-micropost.php'; if ( file_exists($plugin_template) ) return $plugin_template; } } // Deaktiveret for tags, så din egen Site Editor skabelon kan træde i kraft. /* if ( is_tax('micropost_tag') ) { $plugin_template = plugin_dir_path(__FILE__) . 'templates/taxonomy-micropost_tag.php'; if ( file_exists($plugin_template) ) return $plugin_template; } */ /* if ( is_author() ) { $plugin_template = plugin_dir_path(__FILE__) . 'templates/author-micropost.php'; if ( file_exists($plugin_template) ) return $plugin_template; } */ return $template; } add_action( 'add_meta_boxes', function() { add_meta_box( 'ansico_micropost_meta', 'Micropost Details', 'ansico_micropost_meta_html', 'micropost', 'normal', 'high' ); }); function ansico_micropost_meta_html( $post ) { $url = get_post_meta( $post->ID, 'ansico_micropost_url', true ); $time = get_post_meta( $post->ID, 'ansico_micropost_time', true ); $is_federated = ansico_is_micropost_federated( $post->ID ); wp_nonce_field( 'ansico_micropost_save', 'ansico_micropost_nonce' ); ?>



    ID ) && get_post_type( $wp_object->ID ) === 'micropost' ) { update_post_meta( intval( $wp_object->ID ), '_ansico_has_been_federated', '1' ); } } add_action( 'activitypub_mark_wp_object_as_federated', 'ansico_mark_micropost_as_federated' ); /* ========================================================================== 3. RENDERING ENGINE ========================================================================== */ function ansico_get_like_count( $object_type, $object_id ) { $object_id = intval( $object_id ); if ( $object_id < 1 ) { return 0; } if ( $object_type === 'comment' ) { return max( 0, intval( get_comment_meta( $object_id, '_ansico_like_count', true ) ) ); } return max( 0, intval( get_post_meta( $object_id, '_ansico_like_count', true ) ) ); } function ansico_get_user_liked_items( $user_id, $object_type ) { $meta_key = $object_type === 'comment' ? '_ansico_liked_comments' : '_ansico_liked_posts'; $liked = get_user_meta( intval( $user_id ), $meta_key, true ); return is_array( $liked ) ? array_values( array_unique( array_map( 'intval', $liked ) ) ) : array(); } function ansico_user_has_liked( $object_type, $object_id, $user_id = 0 ) { $user_id = $user_id ? intval( $user_id ) : get_current_user_id(); $object_id = intval( $object_id ); if ( $user_id < 1 || $object_id < 1 ) { return false; } return in_array( $object_id, ansico_get_user_liked_items( $user_id, $object_type ), true ); } function ansico_toggle_like( $object_type, $object_id, $user_id = 0 ) { $user_id = $user_id ? intval( $user_id ) : get_current_user_id(); $object_id = intval( $object_id ); if ( $user_id < 1 || $object_id < 1 ) { return new WP_Error( 'ansico_like_forbidden', 'Kun loggede brugere kan like.', array( 'status' => 403 ) ); } if ( $object_type === 'comment' ) { $comment = get_comment( $object_id ); if ( ! $comment || intval( $comment->comment_approved ) !== 1 ) { return new WP_Error( 'ansico_like_invalid_comment', 'Kommentaren findes ikke.', array( 'status' => 404 ) ); } $liked = ansico_get_user_liked_items( $user_id, 'comment' ); $has_liked = in_array( $object_id, $liked, true ); if ( $has_liked ) { $liked = array_values( array_diff( $liked, array( $object_id ) ) ); update_user_meta( $user_id, '_ansico_liked_comments', $liked ); $count = max( 0, ansico_get_like_count( 'comment', $object_id ) - 1 ); update_comment_meta( $object_id, '_ansico_like_count', $count ); return array( 'liked' => false, 'count' => $count ); } $liked[] = $object_id; update_user_meta( $user_id, '_ansico_liked_comments', array_values( array_unique( array_map( 'intval', $liked ) ) ) ); $count = ansico_get_like_count( 'comment', $object_id ) + 1; update_comment_meta( $object_id, '_ansico_like_count', $count ); return array( 'liked' => true, 'count' => $count ); } $post = get_post( $object_id ); if ( ! $post || $post->post_status !== 'publish' || $post->post_type !== 'micropost' ) { return new WP_Error( 'ansico_like_invalid_post', 'Microposten findes ikke.', array( 'status' => 404 ) ); } $liked = ansico_get_user_liked_items( $user_id, 'post' ); $has_liked = in_array( $object_id, $liked, true ); if ( $has_liked ) { $liked = array_values( array_diff( $liked, array( $object_id ) ) ); update_user_meta( $user_id, '_ansico_liked_posts', $liked ); $count = max( 0, ansico_get_like_count( 'post', $object_id ) - 1 ); update_post_meta( $object_id, '_ansico_like_count', $count ); return array( 'liked' => false, 'count' => $count ); } $liked[] = $object_id; update_user_meta( $user_id, '_ansico_liked_posts', array_values( array_unique( array_map( 'intval', $liked ) ) ) ); $count = ansico_get_like_count( 'post', $object_id ) + 1; update_post_meta( $object_id, '_ansico_like_count', $count ); return array( 'liked' => true, 'count' => $count ); } function ansico_render_like_button( $object_type, $object_id, $extra_classes = '' ) { $object_id = intval( $object_id ); if ( $object_id < 1 ) { return ''; } $count = ansico_get_like_count( $object_type, $object_id ); $is_logged_in = is_user_logged_in(); $has_liked = $is_logged_in ? ansico_user_has_liked( $object_type, $object_id ) : false; $classes = trim( 'ansico-action-btn ansico-like-btn ' . $extra_classes . ( $has_liked ? ' is-liked' : '' ) ); $disabled_attr = $is_logged_in ? '' : ' disabled aria-disabled="true" tabindex="-1"'; $title = $is_logged_in ? ( $has_liked ? 'Fjern like' : 'Like' ) : 'Log ind for at like'; return ''; } function ansico_get_tweet_html($author_id, $text, $time_str, $source_url, $embed_data = null, $post_id = 0) { $name = get_the_author_meta( 'display_name', $author_id ); $avatar = get_avatar_url( $author_id, array( 'size' => 50 ) ); if (!$embed_data) { preg_match('/(?{}\[\]]+))/i', $text, $matches); if ($matches) { $embed_data = ansico_fetch_metadata_internal($matches[0]); } } $time_display = $time_str; if ( strtotime($time_str) ) { $ts = strtotime($time_str); $time_display = wp_date(get_option('date_format'), $ts) . ' · ' . wp_date(get_option('time_format'), $ts); } $text = ansico_apply_micropost_text_formatting( $text ); $comment_count = $post_id ? get_comments_number($post_id) : 0; $permalink = $post_id ? get_permalink($post_id) : $source_url; $like_button = $post_id ? ansico_render_like_button( 'post', $post_id ) : ''; $is_federated = $post_id ? ansico_is_micropost_federated( $post_id ) : false; ob_start(); ?>
    $post_id, 'status' => 'approve', 'order' => 'ASC')); if ($comments) { echo '

    ' . esc_html__( 'Replies', 'ansico-some-plugin' ) . '

    '; echo '
      '; wp_list_comments(array( 'style' => 'ul', 'short_ping' => true, 'callback' => 'ansico_custom_comment_markup', ), $comments); echo '
    '; } if ( is_user_logged_in() ) { comment_form(array( 'title_reply' => '', 'title_reply_to' => '', 'comment_notes_before' => '', 'class_submit' => 'ansico-twitter-reply-btn', 'label_submit' => __( 'Reply', 'ansico-some-plugin' ), 'class_form' => 'ansico-twitter-reply-form', 'logged_in_as' => '', 'must_log_in' => '', 'comment_field' => '
    ', ), $post_id); } ?>
    0 ) { $commentdata['comment_author_url'] = get_author_posts_url( $user_id ); } return $commentdata; } /* ========================================================================== 4. BLOCKS & API ========================================================================== */ add_action( 'init', 'ansico_some_register_all' ); function ansico_some_register_all() { wp_register_script( 'ansico-blocks-js', plugins_url( 'block.js', __FILE__ ), array( 'wp-blocks', 'wp-element', 'wp-block-editor', 'wp-data', 'wp-components', 'wp-core-data' ), ANSICO_SOME_PLUGIN_VERSION ); wp_register_style( 'ansico-style', plugins_url( 'style.css', __FILE__ ), array(), ANSICO_SOME_PLUGIN_VERSION ); register_block_type( 'ansico/some-author', array( 'editor_script' => 'ansico-blocks-js', 'style' => 'ansico-style', 'render_callback' => 'ansico_render_author' ) ); register_block_type( 'ansico/some-comment', array( 'editor_script' => 'ansico-blocks-js', 'style' => 'ansico-style', 'render_callback' => 'ansico_render_comment' ) ); register_block_type( 'ansico/embed-url', array( 'editor_script' => 'ansico-blocks-js', 'style' => 'ansico-style' ) ); register_block_type( 'ansico/micropost-form', array( 'editor_script' => 'ansico-blocks-js', 'style' => 'ansico-style', 'render_callback' => 'ansico_render_micropost_form' ) ); register_block_type( 'ansico/micropost-search', array( 'editor_script' => 'ansico-blocks-js', 'style' => 'ansico-style', 'render_callback' => 'ansico_render_micropost_search' ) ); register_block_type( 'ansico/micropost-list', array( 'editor_script' => 'ansico-blocks-js', 'style' => 'ansico-style', 'render_callback' => 'ansico_render_micropost_list', 'attributes' => array( 'postsPerPage' => array( 'type' => 'number', 'default' => 20, ), 'tagFilter' => array( 'type' => 'string', 'default' => '', ), ), ) ); register_block_type( 'ansico/micropost-comments', array( 'editor_script' => 'ansico-blocks-js', 'style' => 'ansico-style', 'render_callback' => 'ansico_render_micropost_comments', 'attributes' => array( 'commentsToShow' => array( 'type' => 'number', 'default' => 5, ), ), ) ); register_block_type( 'ansico/micropost-top-tags', array( 'editor_script' => 'ansico-blocks-js', 'style' => 'ansico-style', 'render_callback' => 'ansico_render_micropost_top_tags', 'attributes' => array( 'tagsToShow' => array( 'type' => 'number', 'default' => 10, ), ), ) ); register_block_type( 'ansico/micropost-activity', array( 'editor_script' => 'ansico-blocks-js', 'style' => 'ansico-style', 'render_callback' => 'ansico_render_micropost_activity', 'attributes' => array( 'itemsPerPage' => array( 'type' => 'number', 'default' => 10, ), ), ) ); } function ansico_get_author_micropost_comment_count( $author_id ) { $author_id = intval( $author_id ); if ( $author_id < 1 ) { return 0; } return (int) get_comments( array( 'user_id' => $author_id, 'status' => 'approve', 'post_type' => 'micropost', 'type' => 'comment', 'count' => true, ) ); } function ansico_get_social_profile_fields() { return array( 'facebook' => array( 'label' => 'Facebook', 'abbr' => 'f' ), 'twitter' => array( 'label' => 'Twitter/X', 'abbr' => 'X' ), 'bluesky' => array( 'label' => 'Bluesky', 'abbr' => 'B' ), 'threads' => array( 'label' => 'Threads', 'abbr' => '@' ), 'mastodon' => array( 'label' => 'Mastodon', 'abbr' => 'M' ), 'instagram' => array( 'label' => 'Instagram', 'abbr' => 'I' ), 'linkedin' => array( 'label' => 'LinkedIn', 'abbr' => 'in' ), 'friendica' => array( 'label' => 'Friendica', 'abbr' => 'F' ), 'pixelfed' => array( 'label' => 'Pixelfed', 'abbr' => 'P' ), ); } function ansico_get_visible_social_profiles( $user_id ) { $profiles = array(); foreach ( ansico_get_social_profile_fields() as $key => $field ) { $url = trim( (string) get_user_meta( $user_id, 'ansico_social_' . $key . '_url', true ) ); $show = ! empty( get_user_meta( $user_id, 'ansico_social_' . $key . '_show', true ) ); if ( $show && ! empty( $url ) ) { $profiles[ $key ] = array( 'label' => $field['label'], 'abbr' => $field['abbr'], 'url' => esc_url( $url ), ); } } return $profiles; } function ansico_render_social_profile_links( $user_id ) { $profiles = ansico_get_visible_social_profiles( $user_id ); if ( empty( $profiles ) ) { return ''; } $html = ''; return $html; } function ansico_render_author_intro_html( $author_id ) { $author_name = get_the_author_meta('display_name', $author_id); $author_avatar = get_avatar_url($author_id, array('size' => 120)); $post_count = count_user_posts($author_id, 'micropost'); $comment_count = ansico_get_author_micropost_comment_count( $author_id ); $author_bio = get_the_author_meta('description', $author_id); $author_website = get_the_author_meta('user_url', $author_id); $social_links = ansico_render_social_profile_links( $author_id ); if ($author_bio) { $author_bio = esc_html($author_bio); $author_bio = preg_replace('/(?<=^|\s|>|>)@([a-zA-Z0-9_]+)@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/i', '@$1@$2', $author_bio); $author_bio = make_clickable($author_bio); $author_bio = preg_replace('/>https?:\/\/(www\.)?([^<]+)<\/a>/i', '>$2', $author_bio); $author_bio = wpautop($author_bio); } ob_start(); ?>
    0 /
    slug) ) $tag_filter = $current_term->slug; } $author_filter = is_author() ? get_queried_object_id() : 0; $ppp = isset($attributes['postsPerPage']) ? intval($attributes['postsPerPage']) : 20; $query_args = array( 'post_type' => 'micropost', 'posts_per_page' => $is_single_micropost ? 1 : $ppp, 'paged' => $paged, 'orderby' => 'date', 'order' => 'DESC' ); if (!empty($search_query)) { $matching_ids = ansico_get_micropost_ids_matching_search( $search_query ); $query_args['post__in'] = !empty($matching_ids) ? $matching_ids : array(0); } if ($is_single_micropost) $query_args['p'] = get_the_ID(); if ($author_filter) $query_args['author'] = $author_filter; if (!empty($tag_filter)) { $tag_filter = ltrim($tag_filter, '#'); $query_args['tax_query'] = array(array('taxonomy' => 'micropost_tag', 'field' => 'slug', 'terms' => $tag_filter)); } $query = new WP_Query($query_args); ob_start(); // Vis forfatter intro hvis vi er på en forfatter side if ( is_author() && $paged == 1 && empty($search_query) ) { $author_id = get_queried_object_id(); echo ansico_render_author_intro_html( $author_id ); } echo '
    '; if ($query->have_posts()) { while ($query->have_posts()) { $query->the_post(); $url = get_post_meta(get_the_ID(), 'ansico_micropost_url', true); $time = get_post_meta(get_the_ID(), 'ansico_micropost_time', true); echo ansico_get_tweet_html(get_the_author_meta('ID'), get_the_content(), $time, $url, null, get_the_ID()); } if ( !$is_single_micropost ) { $big = 999999999; echo '
    '; echo paginate_links(array( 'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))), 'format' => '?paged=%#%', 'current' => max(1, $paged), 'total' => $query->max_num_pages, 'prev_text' => '« Forrige', 'next_text' => __( 'Next »', 'ansico-some-plugin' ), )); echo '
    '; } wp_reset_postdata(); } echo '
    '; return ob_get_clean(); } function ansico_render_micropost_top_tags($attributes) { $tags_to_show = isset($attributes['tagsToShow']) ? intval($attributes['tagsToShow']) : 10; if ($tags_to_show < 1) { $tags_to_show = 1; } $terms = get_terms(array( 'taxonomy' => 'micropost_tag', 'hide_empty' => true, 'number' => $tags_to_show, 'orderby' => 'count', 'order' => 'DESC', )); if (is_wp_error($terms) || empty($terms)) { return ''; } ob_start(); echo '
    '; echo '
    '; foreach ($terms as $term) { $term_link = get_term_link($term); if (is_wp_error($term_link)) { continue; } echo ''; echo '#' . esc_html($term->name) . ''; echo '' . intval($term->count) . ''; echo ''; } echo '
    '; echo '
    '; return ob_get_clean(); } function ansico_render_micropost_comments($attributes) { $comments_to_show = isset($attributes['commentsToShow']) ? intval($attributes['commentsToShow']) : 5; if ($comments_to_show < 1) { $comments_to_show = 1; } $comments = get_comments(array( 'status' => 'approve', 'number' => $comments_to_show, 'orderby' => 'comment_date_gmt', 'order' => 'DESC', 'post_type' => 'micropost', 'type__in' => array('', 'comment'), )); if (empty($comments)) { return ''; } ob_start(); echo '
    '; foreach ($comments as $comment) { echo ansico_render_activity_comment_item($comment); } echo '
    '; return ob_get_clean(); } function ansico_render_activity_comment_item( $comment ) { $post_id = isset($comment->comment_post_ID) ? intval($comment->comment_post_ID) : 0; if (!$post_id || get_post_type($post_id) !== 'micropost') { return ''; } $micropost_permalink = get_permalink($post_id); $comment_permalink = get_comment_link($comment); $reply_permalink = $micropost_permalink ? add_query_arg( 'replytocom', intval( $comment->comment_ID ), $micropost_permalink ) . '#respond' : ''; $author_url = ''; if ( is_object( $comment ) && ! empty( $comment->user_id ) ) { $author_url = get_author_posts_url( (int) $comment->user_id ); } elseif ( is_object( $comment ) && ! empty( $comment->comment_author_url ) ) { $author_url = $comment->comment_author_url; } $author_name = get_comment_author($comment); $avatar = get_avatar($comment, 40, '', '', array('class' => 'ansico-tweet-avatar')); $avatar_html = $author_url ? '' . $avatar . '' : $avatar; $time_display = get_comment_date( get_option('date_format'), $comment ) . ' · ' . get_comment_time( get_option('time_format'), false, false, $comment ); $comment_text = ansico_get_formatted_comment_html( $comment ); $reply_count = get_comments(array( 'post_id' => $post_id, 'parent' => intval($comment->comment_ID), 'status' => 'approve', 'count' => true, 'type__in' => array('', 'comment'), )); $like_button = ansico_render_like_button( 'comment', $comment->comment_ID ); ob_start(); echo '
    '; echo '
    '; echo '
    '; if ($micropost_permalink) { echo ''; echo ''; echo ''; } echo "'; echo '
    '; echo '
    ' . $avatar_html . '
    '; echo '
    '; echo '
    '; if (!empty($author_url)) { echo '' . esc_html($author_name) . ''; } else { echo '' . esc_html($author_name) . ''; } echo '' . esc_html( wp_strip_all_tags( $time_display ) ) . ''; echo '
    '; echo '
    ' . wp_kses_post( $comment_text ) . '
    '; echo '
    '; if ($like_button) { echo $like_button; } if ($reply_permalink) { echo ''; echo ''; echo '' . intval($reply_count) . ''; echo ''; } echo '
    '; echo '
    '; echo '
    '; echo '
    '; return ob_get_clean(); } function ansico_render_micropost_activity($attributes) { global $wpdb; $items_per_page = isset($attributes['itemsPerPage']) ? intval($attributes['itemsPerPage']) : 10; if ($items_per_page < 1) { $items_per_page = 1; } $current_page = isset($_GET['ansico_activity_page']) ? intval($_GET['ansico_activity_page']) : 1; if ($current_page < 1) { $current_page = 1; } $offset = ($current_page - 1) * $items_per_page; $posts_table = $wpdb->posts; $comments_table = $wpdb->comments; $total_posts = (int) $wpdb->get_var( "SELECT COUNT(ID) FROM {$posts_table} WHERE post_type = 'micropost' AND post_status = 'publish'" ); $total_comments = (int) $wpdb->get_var( "SELECT COUNT(c.comment_ID) FROM {$comments_table} c INNER JOIN {$posts_table} p ON c.comment_post_ID = p.ID WHERE c.comment_approved = '1' AND (c.comment_type = '' OR c.comment_type = 'comment') AND p.post_type = 'micropost' AND p.post_status = 'publish'" ); $total_items = $total_posts + $total_comments; if ($total_items < 1) { return ''; } $query = $wpdb->prepare( "(SELECT ID AS object_id, post_date_gmt AS event_date_gmt, 'post' AS event_type FROM {$posts_table} WHERE post_type = 'micropost' AND post_status = 'publish') UNION ALL (SELECT c.comment_ID AS object_id, c.comment_date_gmt AS event_date_gmt, 'comment' AS event_type FROM {$comments_table} c INNER JOIN {$posts_table} p ON c.comment_post_ID = p.ID WHERE c.comment_approved = '1' AND (c.comment_type = '' OR c.comment_type = 'comment') AND p.post_type = 'micropost' AND p.post_status = 'publish') ORDER BY event_date_gmt DESC LIMIT %d OFFSET %d", $items_per_page, $offset ); $rows = $wpdb->get_results($query); if (empty($rows)) { return ''; } ob_start(); echo '
    '; foreach ($rows as $row) { if ($row->event_type === 'post') { $post = get_post((int) $row->object_id); if (!$post || $post->post_status !== 'publish' || $post->post_type !== 'micropost') { continue; } $url = get_post_meta($post->ID, 'ansico_micropost_url', true); $time = get_post_meta($post->ID, 'ansico_micropost_time', true); echo '
    '; echo ansico_get_tweet_html($post->post_author, $post->post_content, $time, $url, null, $post->ID); echo '
    '; } else { $comment = get_comment((int) $row->object_id); if (!$comment) { continue; } echo ansico_render_activity_comment_item($comment); } } $total_pages = (int) ceil($total_items / $items_per_page); if ($total_pages > 1) { $pagination = paginate_links(array( 'base' => esc_url_raw(add_query_arg('ansico_activity_page', '%#%')), 'format' => '', 'current' => $current_page, 'total' => $total_pages, 'type' => 'list', 'prev_text' => '« Forrige', 'next_text' => __( 'Next »', 'ansico-some-plugin' ), )); if ($pagination) { echo ''; } } echo '
    '; return ob_get_clean(); } add_action( 'rest_api_init', function () { register_rest_route( 'ansico/v1', '/create-micropost', array( 'methods' => 'POST', 'callback' => 'ansico_rest_create', 'permission_callback' => function() { return is_user_logged_in(); } ) ); register_rest_route( 'ansico/v1', '/toggle-like', array( 'methods' => 'POST', 'callback' => 'ansico_rest_toggle_like', 'permission_callback' => function() { return is_user_logged_in(); }, ) ); }); function ansico_rest_create($req) { $text = sanitize_textarea_field($req['text']); $max_chars = ansico_get_micropost_max_chars(); if (empty($text)) { return array('success' => false, 'message' => 'Tom micropost.'); } if ( function_exists( 'mb_strlen' ) ? mb_strlen( $text ) > $max_chars : strlen( $text ) > $max_chars ) { return array('success' => false, 'message' => __( 'Micropost is too long.', 'ansico-some-plugin' )); } $post_id = wp_insert_post(array('post_type' => 'micropost', 'post_content' => $text, 'post_status' => 'publish', 'comment_status' => 'open')); if ($post_id) { update_post_meta($post_id, 'ansico_micropost_time', current_time('mysql')); update_post_meta($post_id, 'ansico_micropost_url', get_permalink($post_id)); return array('success' => true); } return array('success' => false, 'message' => __( 'Could not create micropost.', 'ansico-some-plugin' )); } function ansico_fetch_metadata_internal($url) { $response = wp_remote_get( $url ); if ( is_wp_error( $response ) ) return null; $html = wp_remote_retrieve_body( $response ); libxml_use_internal_errors(true); $doc = new DOMDocument(); @$doc->loadHTML( mb_convert_encoding( $html, 'HTML-ENTITIES', 'UTF-8' ) ); libxml_clear_errors(); $res = array('title' => '', 'image' => '', 'domain' => str_replace('www.', '', wp_parse_url($url, PHP_URL_HOST))); $tags = $doc->getElementsByTagName('meta'); foreach ($tags as $tag) { if ($tag->getAttribute('property') === 'og:title') $res['title'] = $tag->getAttribute('content'); if ($tag->getAttribute('property') === 'og:image') $res['image'] = $tag->getAttribute('content'); } if(empty($res['title'])) { $t = $doc->getElementsByTagName('title'); if($t->length > 0) $res['title'] = $t->item(0)->nodeValue; } return $res; } /* ========================================================================== 5. AVATAR FILTERS ========================================================================== */ add_filter( 'get_avatar_url', function( $url, $id_or_email, $args ) { $user_id = null; if ( is_numeric( $id_or_email ) ) { $user_id = $id_or_email; } elseif ( is_object( $id_or_email ) && isset( $id_or_email->user_id ) ) { $user_id = $id_or_email->user_id; } if ( $user_id ) { $custom = get_user_meta( $user_id, 'ansico_avatar_url', true ); if ( $custom ) return $custom; } return $url; }, 10, 3 ); add_action( 'show_user_profile', 'ansico_avatar_field' ); add_action( 'edit_user_profile', 'ansico_avatar_field' ); function ansico_avatar_field($user) { $url = get_user_meta($user->ID, 'ansico_avatar_url', true); echo '

    ' . esc_html__( 'Profilbillede', 'ansico-some-plugin' ) . '

    Profilbillede
    '; echo '

    ' . esc_html__( 'Social profiles', 'ansico-some-plugin' ) . '

    '; echo ''; foreach ( ansico_get_social_profile_fields() as $key => $field ) { $profile_url = get_user_meta( $user->ID, 'ansico_social_' . $key . '_url', true ); $show_on_profile = ! empty( get_user_meta( $user->ID, 'ansico_social_' . $key . '_show', true ) ); echo ''; echo ''; echo ''; echo ''; } echo ''; } function ansico_rest_toggle_like( WP_REST_Request $request ) { $object_type = sanitize_key( (string) $request->get_param( 'object_type' ) ); $object_id = intval( $request->get_param( 'object_id' ) ); if ( ! in_array( $object_type, array( 'post', 'comment' ), true ) ) { return new WP_Error( 'ansico_like_invalid_type', __( 'Invalid like type.', 'ansico-some-plugin' ), array( 'status' => 400 ) ); } $result = ansico_toggle_like( $object_type, $object_id, get_current_user_id() ); if ( is_wp_error( $result ) ) { return $result; } return rest_ensure_response( array( 'liked' => ! empty( $result['liked'] ), 'count' => intval( $result['count'] ), ) ); } add_action( 'personal_options_update', 'ansico_save_avatar' ); add_action( 'edit_user_profile_update', 'ansico_save_avatar' ); function ansico_save_avatar($user_id) { if(isset($_POST['ansico_avatar_url'])) update_user_meta($user_id, 'ansico_avatar_url', esc_url_raw($_POST['ansico_avatar_url'])); $social_input = isset( $_POST['ansico_social'] ) && is_array( $_POST['ansico_social'] ) ? $_POST['ansico_social'] : array(); foreach ( ansico_get_social_profile_fields() as $key => $field ) { $row = isset( $social_input[ $key ] ) && is_array( $social_input[ $key ] ) ? $social_input[ $key ] : array(); $url = isset( $row['url'] ) ? esc_url_raw( trim( wp_unslash( $row['url'] ) ) ) : ''; $show = ! empty( $row['show'] ) ? '1' : ''; update_user_meta( $user_id, 'ansico_social_' . $key . '_url', $url ); update_user_meta( $user_id, 'ansico_social_' . $key . '_show', $show ); } } add_action( 'admin_enqueue_scripts', function( $hook ) { if ( 'profile.php' === $hook || 'user-edit.php' === $hook ) { wp_enqueue_media(); wp_enqueue_script( 'ansico-admin', plugins_url( 'admin-script.js', __FILE__ ), array( 'jquery' ), ANSICO_SOME_PLUGIN_VERSION, true ); wp_localize_script( 'ansico-admin', 'ansicoAdminSettings', array( 'cleanUpProfileSettings' => ! empty( get_option( 'ansico_clean_up_profile_settings', '' ) ), 'labels' => array( 'profile' => __( 'Profile', 'ansico-some-plugin' ), 'federation' => __( 'Federation', 'ansico-some-plugin' ), 'otherSettings' => __( 'Other settings', 'ansico-some-plugin' ), ), ) ); } } ); add_action( 'admin_head-profile.php', 'ansico_render_profile_cleanup_admin_css' ); add_action( 'admin_head-user-edit.php', 'ansico_render_profile_cleanup_admin_css' ); function ansico_render_profile_cleanup_admin_css() { if ( empty( get_option( 'ansico_clean_up_profile_settings', '' ) ) ) { return; } ?>