jgoldbloom
Forum Replies Created
-
Forum: Plugins
In reply to: [Asgaros Forum] Ajax support for recent topics/posts widgets@asgaros and anyone interested:
Below is how I implemented in my child theme functions.php by writing my own forum-widget (for now), adding a custom function to render it via shortcode with instance argument support for shortcode type (topics vs. post and total (i.e. 10) like your widget. To render it I simply added shortcode to call my widget via a custom text widget in my theme sidebar setup, easy as that and no embedded PHP in the no cache AJAX widget which would be a huge security hole. See comments in my code for shortcode syntax.
Pick out what you need, hope you streamline and improve as my method overall is for my own custom widgets and others, not just Asgaros while you were away:
1. Install https://www.ads-software.com/plugins/no-cache-ajax-widgets/
2. In functions.php:/* Render widget via shortcode. Shortcode examples for post/page/sidebars widgets/No Cache AJAX Widgets (plugin), etc.: [cdsnWidget widget_name="cdsn_forum_activity_widget" instance="type=topics&total=10"] [cdsnWidget widget_name="cdsn_forum_activity_widget" instance="type=posts&total=10"] */ function cdsnWidgetShortCode($atts) { global $wp_widget_factory; extract(shortcode_atts(array( 'widget_name' => FALSE, 'instance' => FALSE, ), $atts)); $instance = str_ireplace("&", '&' ,$instance); $widget_name = wp_specialchars($widget_name); if (!is_a($wp_widget_factory->widgets[$widget_name], 'WP_Widget')): $wp_class = 'WP_Widget_'.ucwords(strtolower($class)); if (!is_a($wp_widget_factory->widgets[$wp_class], 'WP_Widget')): return '<p>'.sprintf(__("%s: Widget class not found. Make sure this widget exists and the class name is correct"),'<strong>'.$class.'</strong>').'</p>'; else: $class = $wp_class; endif; endif; ob_start(); the_widget($widget_name, $instance, array('widget_id'=>'arbitrary-instance-'.$id, 'before_widget' => '', 'after_widget' => '', 'before_title' => '', 'after_title' => '', )); $output = ob_get_contents(); ob_end_clean(); return $output; } /* ======================================= Widget class cdsn_forum_activity_widget ======================================= This class creates a widget showing most recent Asgaros forum activity due to Ajax issues with native Asgaros widget. Options include widget title and total topics used to limit the SQL query. Load thru Ajax Widget via [cdsnWidget widget_name="cdsn_forum_activity_widget" instance="type=x&total=y"] where "x" is type (either topics or posts) and "y" is query limit, i.e 10. */ class cdsn_forum_activity_widget extends WP_Widget { function __construct() { parent::__construct( // Base ID - this is the widget name in WP 'cdsn_forum_activity_widget', // Widget name will appear in UI __('CDSN Forum Recent Activity (Asgaros)', 'cdsn_forum_activity_widget_domain'), // Widget description array( 'description' => __( 'Load thru Ajax Widget via [cdsnWidget widget_name="cdsn_forum_activity_widget" instance="type=x&total=y"] where "x" is type (either topics or posts) and "y" is query limit, i.e 10', 'cdsn_forum_activity_widget_domain' ), ) ); } // Creating widget front-end and establish widget display options // This is where the action happens public function widget( $args, $instance ) { $title = apply_filters( 'widget_title', $instance['title'] ); $limit = intval($instance['total']); $type = $instance['type']; // before and after widget arguments are defined by themes echo $args['before_widget']; if ( ! empty( $title ) ) {echo $args['before_title'] . $title . $args['after_title'];} /* --------------------------- Code to perform widget task --------------------------- */ global $wpdb; $excludeForumIDs="36"; // Query for topic data based on instance type if ($type=='topics') { $query=" SELECT p1.text, p1.id, p1.date as postdate, p1.parent_id, p1.author_id, t.name, u.display_name, um.meta_value as avatar, (SELECT COUNT(id) FROM wp_forum_posts WHERE parent_id=p1.parent_id) AS post_counter FROM wp_forum_posts AS p1 LEFT JOIN wp_forum_posts AS p2 ON (p1.parent_id = p2.parent_id AND p1.id > p2.id) LEFT JOIN wp_forum_topics AS t ON (t.id = p1.parent_id) LEFT JOIN wp_forum_forums AS f ON (f.id = t.parent_id) LEFT JOIN wp_users AS u ON (u.id = p1.author_id) LEFT JOIN wp_usermeta AS um ON (um.user_id = p1.author_id and meta_key = 'profile_photo') WHERE p2.id IS NULL AND f.parent_id NOT IN ($excludeForumIDs) ORDER BY t.id DESC LIMIT $limit"; } // Query for posts data based on instance type else { $query=" SELECT p1.text, p1.id, p1.date as postdate, p1.parent_id, p1.author_id, t.name, u.display_name, um.meta_value as avatar, (SELECT COUNT(id) FROM wp_forum_posts WHERE parent_id=p1.parent_id) AS post_counter FROM wp_forum_posts AS p1 LEFT JOIN wp_forum_posts AS p2 ON (p1.parent_id = p2.parent_id AND p1.id > p2.id) LEFT JOIN wp_forum_topics AS t ON (t.id = p1.parent_id) LEFT JOIN wp_forum_forums AS f ON (f.id = t.parent_id) LEFT JOIN wp_users AS u ON (u.id = p1.author_id) LEFT JOIN wp_usermeta AS um ON (um.user_id = p1.author_id and meta_key = 'profile_photo') WHERE p2.id IS NULL AND f.parent_id NOT IN ($excludeForumIDs) ORDER BY p1.id DESC LIMIT $limit"; } // Execute our query $posts = $wpdb->get_results($query); $content=''; foreach ($posts as $post) { // Prepare our topic link as this info is not stored in the database $url=get_site_url(); $pageNumber = ceil($post->post_counter / 25); // mtached to # of topics per page in Asgaros $link="{$url}/cdsn-forum/?view=thread&id={$post->parent_id}=&part=$pageNumber#postid-{$post->id}"; // Prepare our avatar handled by Ultimate Member plugin $avatar_info=new SplFileInfo($post->avatar); $avatar_ext=$avatar_info->getExtension(); $avatar="{$url}/wp-content/uploads/ultimatemember/{$post->author_id}/profile_photo-40.{$avatar_ext}"; unset ($avatar_info); // Ensure we have a default author name if missing $post->display_name=(!empty($post->display_name)) ? $post->display_name : 'CDSN Member'; // Prepare our content $name=$this->cdsnTruncate(strip_tags($this->cdsnSanitize($post->name)),33); $link=$this->cdsnSanitize($link); $author=$this->cdsnSanitize($post->display_name); date_default_timezone_set('America/New_York'); $date=$this->cdsnTimeAgo($post->postdate); $postCounter=$post->post_counter-1; if ($postCounter>1) { $postCounter=", $postCounter replies"; } elseif ($postCounter==1) { $postCounter=", 1 reply"; } else { $postCounter=''; } // Pepare debug info (HTML) $debug="query=$query<br><br>type=$type<br>name=$name<br>link=$link<br> date=$date<br>author=$author<br>avatar=$avatar<br>"; // Pepare content (HTML) $content.=" <div class='asgarosforum-widget'> <div class='widget-element cdsnWidgetElement'> <div class='widget-avatar cdsnWidgetAvatar'> <img src='$avatar' alt='Author profile pic...' /> </div> <div class='widget-content'> <span class='post-link'><a href='$link' title='$lnk...'>$name</a></span> <span class='post-author'>by <span class='cdsnWidgetAuthor'>$author</span></span> <span class='post-date cdsnWidgetDate'>$date$postCounter</span> </div> </div> </div> "; } // Display prepared content // echo __( $debug.$content, 'cdsn_forum_activity_widget_domain' ); echo __( $content, 'cdsn_forum_activity_widget_domain' ); echo $args['after_widget']; } // Widget Backend public function form( $instance ) { // Title if ( isset( $instance[ 'title' ] ) && !empty($instance[ 'title' ]) ) {$title = $instance[ 'title' ];} else {$title = __( 'Recent Forum Activity', 'cdsn_forum_activity_widget_domain' );} // Total topics if ( isset( $instance[ 'total' ] ) && !empty($instance[ 'total' ]) ) {$total = $instance[ 'total' ];} else {$total = __( '10', 'cdsn_forum_activity_widget_domain' );} // Type if ( isset( $instance[ 'type' ] ) && !empty($instance[ 'type' ]) ) { $type = $instance[ 'type' ]; $checkedTopics = ($instance[ 'type' ]=='topics') ? "checked" : ''; $checkedPosts = ($instance[ 'type' ]=='posts') ? "checked" : ''; } else { $type = __( 'topics', 'cdsn_forum_activity_widget_domain' ); $checkedTopics='checked'; $checkedPosts=''; } // Widget admin form - widget options ?> <p> <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label> <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" /> </p> <p> <label for="<?php echo $this->get_field_id( 'type' ); ?>"><?php _e( 'Type:' ); ?></label> <input class="radio" id="<?php echo $this->get_field_id( 'type' ); ?>" name="<?php echo $this->get_field_name( 'type' ); ?>" type="radio" value="topics" <?php echo $checkedTopics; ?> />Topics <input class="radio" id="<?php echo $this->get_field_id( 'type' ); ?>" name="<?php echo $this->get_field_name( 'type' ); ?>" type="radio" value="posts" <?php echo $checkedPosts; ?> />Posts </p> <p> <label for="<?php echo $this->get_field_id( 'total' ); ?>"><?php _e( 'Total Topics:' ); ?></label> <input class="tiny-text" id="<?php echo $this->get_field_id( 'total' ); ?>" name="<?php echo $this->get_field_name( 'total' ); ?>" type="number" step="1" min="1" value="<?php echo esc_attr( $total ); ?>" /> </p> <?php } // Updating widget replacing old instances with new public function update( $new_instance, $old_instance ) { $instance = array(); $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : ''; $instance['total'] = ( ! empty( $new_instance['total'] ) ) ? $new_instance['total'] : '10'; $instance['type'] = ( ! empty( $new_instance['type'] ) ) ? $new_instance['type'] : 'topics'; return $instance; } /* CUSTOM CDSN FUNCTIONS BEGIN */ // Sanitize query data to ensure properly escaped and newlines converted to HTML line breaks private function cdsnSanitize($str) { return nl2br(stripslashes($str),false); } // Truncate a string to configured size/nearest word private function cdsnTruncate($text, $length) { $length = abs((int)$length); if(strlen($text) > $length) { $text = preg_replace("/^(.{1,$length})(\s.*|$)/s", '\\1...', $text); } return($text); } // Date to "time ago" in Facebook style human readable format private function cdsnTimeAgo($timestamp) { $time_ago = strtotime($timestamp); $current_time = time(); $time_difference = $current_time - $time_ago; $seconds = $time_difference; $minutes = round($seconds / 60 ); // value 60 is seconds $hours = round($seconds / 3600); // value 3600 is 60 minutes * 60 sec $days = round($seconds / 86400); // 86400 = 24 * 60 * 60; $weeks = round($seconds / 604800); // 7*24*60*60; $months = round($seconds / 2629440); // ((365+365+365+365+366)/5/12)*24*60*60 $years = round($seconds / 31553280); // (365+365+365+365+366)/5 * 24 * 60 * 60 if($seconds <= 60) { return "Just now"; } else if($minutes <=60) { if($minutes==1) { return "1 minute ago"; } else { return "$minutes minutes ago"; } } else if($hours <=24) { if($hours==1) { return "1 hour ago"; } else { return "$hours hrs ago"; } } else if($days <= 7) { if($days==1) { return "Yesterday"; } else { return "$days days ago"; } } else if($weeks <= 4.3) //4.3 == 52/12 { if($weeks==1) { return "1 week ago"; } else { return "$weeks weeks ago"; } } else if($months <=12) { if($months==1) { return "1 month ago"; } else { return "$months months ago"; } } else { if($years==1) { return "1 year ago"; } else { return "$years years ago"; } } } } // Class cdsn_forum_activity_widget ends here // Register and load the above widget function cdsn_load_forum_widget() { register_widget( 'cdsn_forum_activity_widget' ); } /* Make it happen */ add_shortcode('cdsnWidget','cdsnWidgetShortCode'); add_action( 'widgets_init', 'cdsn_load_forum_widget' );
To others:
Remember my forum-widget has some hard coded values like forum ID’s to exclude plus I use Ultimate Member plugin so meta content is included for that and my specific site. I included a couple of small helper functions used by this and other widgets/code – FYI.
-jim
- This reply was modified 7 years, 10 months ago by jgoldbloom. Reason: Fixed a typo
- This reply was modified 7 years, 10 months ago by jgoldbloom. Reason: code formatting fix
Forum: Plugins
In reply to: [Asgaros Forum] HTML entities in topic subscription emailsThank you, @asgaros — if any issues I’ll post here when time permits me to test. Cheers and welcome back.
Forum: Plugins
In reply to: [Asgaros Forum] Link to user profiles on forum (Users Ultra)@asgaros – way cool, thanks!
Forum: Plugins
In reply to: [Asgaros Forum] Link to user profiles on forum (Users Ultra)Forgot to ask, does asgarosforum_filter_post_username allow author_id to be passed not just username? Or in my function what code can I use to get that?
Forum: Plugins
In reply to: [Asgaros Forum] Link to user profiles on forum (Users Ultra)Yes, that’s the “programmatic alternative” I noted in my original comment. I’m asking to make it a new feature in the admin setup which I should have clarified. Using the simple macro option to embed author ID in the link for that feature is easy to parse in your code and would fully support other plugins where a profile link almost has the one common element, the ID, fyi.
The reason I suggested the feature request is because linking the avatar and/or author name should be available to non-developers and such a feature is very useful, common and sensible, I think.
Forum: Plugins
In reply to: [Asgaros Forum] tons of redirectsAlso might want to explore Akismet and WP Bruiser plugins for tough post security.
Forum: Plugins
In reply to: [Asgaros Forum] Hook asgarosforum_after_edit_post_submit not firingJust a quick comment the hooks working perfectly in dev, I use them to purge like/dislike meta data in custom fields to ensure the DB is tidy. I also reset likes/dislikes to zero with the legacy edit hook when a post is edited which seems fair! Love ‘dem hooks,.
Forum: Plugins
In reply to: [Asgaros Forum] Ajax support for recent topics/posts widgetsActually I updated my AJAX widget and added a count of replies – hint hint @asgaros after the time ago info, pluralized as needed and no count if no replies yet (which I prefer over “no replies” etc. which is a bummer, heh):
??
Forum: Plugins
In reply to: [Asgaros Forum] HTML entities in topic subscription emailsFor WP you might try: wp_specialchars_decode()
https://developer.www.ads-software.com/reference/functions/wp_specialchars_decode/
Forum: Plugins
In reply to: [Asgaros Forum] HTML entities in topic subscription emailsOnly ASCII is allowed in the subject if UTF-8 encoded, which is the encoding I would use overall, but maybe apply something like the following for the subject line only:
<?php html_entity_decode($subject, ENT_QUOTES | ENT_XML1, 'UTF-8') ?>
… in addition to stripping HTML/slashes for the subject. It’s the &xxx; entities in question here. esc_html() is more or less lossless — it just turns HTML markup into encoded visible text, so that it’s not rendered as markup by browser.
Forum: Plugins
In reply to: [Asgaros Forum] Link to user profiles on forum (Users Ultra)@asgaros – personally, instead of or in addition to adding a custom profile link/button below the avatar, etc. using that hook for the author panel it might be cool to:
- Add an option in settings for a profile link URL that will activate when the avatar itself (or username)
- Allow a macro like %id% to be embeded in the URL to expand to the author ID in the front end
??
p.s. There are programmatic alternatives but this seems like a useful feature for everyone, my .02 — but you get the idea of basically what I mean.
Forum: Plugins
In reply to: [Asgaros Forum] Temporary but working RSS 2.0 forum topic newsfeedTo all, I made two fixes in rss-forum.php since original post, adding proper GUID and post link pagination:
<?php /* Template Name: Custom RSS Template - Feedname (rss-forum.php) - Asgaros recent topics feed (RSS 2.0) */ // Configuration options: $excludeForumIDs="36"; // Comma separated parent forum ID's to exclude fron wp_forum_forums table query $postCount = 25; // The number of posts to show in the feed $truncateSize=350; // How many characters to allow for description (truncated at nearest word) $postsPerPage=25; // matched to # of topics per page in Asgaros for page link caslculation in post url // Function: Sanitize query data to ensure properly escaped and newlines converted to HTML line breaks function cdsnSanitize($str) { return nl2br(stripslashes($str),false); } // Function: Truncate a string to configured size/nearest word function cdsnTruncate($text, $length) { $length = abs((int)$length); if(strlen($text) > $length) { $text = preg_replace("/^(.{1,$length})(\s.*|$)/s", '\\1...', $text); } return($text); } // BEGIN FEED OUPUT header('Content-Type: '.feed_content_type('rss-http').'; charset=UTF-8', true); print '<?xml version="1.0" encoding="UTF-8"?>'; ?> <rss version="2.0" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:media="https://search.yahoo.com/mrss/" <?php do_action('rss2_ns'); ?>> <channel> <title><?php bloginfo_rss('name'); ?> - Recent Forum Activity</title> <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" /> <link><?php bloginfo_rss('url') ?></link> <description><?php bloginfo_rss('description'); ?>...</description> <lastBuildDate><?php print mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false); ?></lastBuildDate> <language>en-us</language> <sy:updatePeriod><?php print apply_filters( 'rss_update_period', 'hourly' ); ?></sy:updatePeriod> <sy:updateFrequency><?php print apply_filters( 'rss_update_frequency', '1' ); ?></sy:updateFrequency> <?php // Query for topic data $query=" SELECT p1.text, p1.id, p1.date, p1.parent_id, p1.author_id, t.name, u.display_name, um.meta_value as avatar, (SELECT COUNT(id) FROM wp_forum_posts WHERE parent_id=p1.parent_id) AS post_counter FROM wp_forum_posts AS p1 LEFT JOIN wp_forum_posts AS p2 ON (p1.parent_id = p2.parent_id AND p1.id > p2.id) LEFT JOIN wp_forum_topics AS t ON (t.id = p1.parent_id) LEFT JOIN wp_forum_forums AS f ON (f.id = t.parent_id) LEFT JOIN wp_users AS u ON (u.id = p1.author_id) LEFT JOIN wp_usermeta AS um ON (um.user_id = p1.author_id and meta_key = 'profile_photo') WHERE p2.id IS NULL AND f.parent_id NOT IN ($excludeForumIDs) ORDER BY t.id DESC LIMIT $postCount;"; // Execute our query $posts = $wpdb->get_results($query); ?> <?php foreach ($posts as $post) { // Prepare our topic link as this is not stored in the database $url=get_site_url(); $pageNumber = ceil($post->post_counter / $postsPerPage); $link="{$url}/cdsn-forum/?view=thread&id={$post->parent_id}=&part=$pageNumber#postid-{$post->id}"; // Prepare our avatar handled by Ultimate Member plugin $avatar_info=new SplFileInfo($post->avatar); $avatar_ext=$avatar_info->getExtension(); $avatar="{$url}/wp-content/uploads/ultimatemember/{$post->author_id}/profile_photo-190.{$avatar_ext}"; unset ($avatar_info); // Ensure we have a default author name if missing $post->display_name=(!empty($post->display_name)) ? $post->display_name : 'CDSN Member'; ?> <item> <title><?php print strip_tags(cdsnSanitize($post->name)); ?></title> <link><![CDATA[<?php print cdsnSanitize($link); ?>]]></link> <pubDate><?php print mysql2date('D, d M Y H:i:s +0000', cdsnSanitize($post->date)); ?></pubDate> <dc:creator><?php print cdsnSanitize($post->display_name); ?></dc:creator> <guid isPermaLink="false"><![CDATA[<?php print cdsnSanitize($link); ?>]]></guid> <description><![CDATA[<?php print cdsnTruncate(cdsnSanitize($post->text),$truncateSize); ?>]]></description> <media:thumbnail url='<?php print $avatar; ?>' height='190' width='190' /> </item> <?php } ?> </channel> </rss>
Marking this topic as resolved.
Forum: Plugins
In reply to: [Asgaros Forum] Temporary but working RSS 2.0 forum topic newsfeed@fahmet – this is an Asgaros support forum and this topic is a feed for that plugin only not bbPress.
508, btw, refers to the website is temporarily unable to service your request as it exceeded resource limit. It happens when the number of processes (RAM/CPU/INODES) exceeds the limits set by the hosting provider. You need to enhance the capacity with your hosting provider or check in the code whether any process takes longer time (like background tasks). Yoast SEO also has its own support forum or switch to All in One SEO which I switched to as Yoast had numerous issues for my site that all went away after switching.
Forum: Plugins
In reply to: [Asgaros Forum] Hook asgarosforum_after_edit_post_submit not firingForum: Plugins
In reply to: [Google Analytics Counter Tracker] WSOD when connecting to GA during setupNow it started working, but I’ll be honest I think your server was non-responsive for a bit (not my connection, not browser specific, popups disabled) and the lack of an error message as I stated was frustrating. FYI.