• Resolved Fee

    (@wdfee)


    Hello Gabriel,
    thanks for your wonderful plugin – it’s really fun!
    I tried to create a custom hook for Favorites in bbPress 2.0 forums: if somebody adds the topic to his favorites, the topic author should get points.
    I followed your tutorial for custom hooks, but didn’t get it working. The hook settings show up in wp admin, but when somebody favorites a topic, no points are added.
    What do you think: would you be interested to add this functionality to the core of your plugin?
    Otherwise – would you mind taking a look at my code if I did something wrong?

    add_filter( 'mycred_setup_hooks', 'register_my_bbp_fav_hook' );
    function register_my_bbp_fav_hook( $installed )
    {
    	$installed['bbp_fav_topic'] = array(
    		'title'       => __( 'bbPress Favorites', 'mytheme' ),
    		'description' => __( 'Give points to topic author when topic is favorited.', 'mytheme' ),
    		'callback'    => array( 'my_bbp_fav_hook' )
    	);
    	return $installed;
    }
    
    if ( !class_exists( 'my_bbp_fav_hook' ) ) {
    	class my_bbp_fav_hook extends myCRED_Hook {
    
    		function __construct( $hook_prefs ) {
    			parent::__construct( array(
    				'id'       => 'bbp_fav_topic',
    				'defaults' => array(
    					'fav_topic' => array(
    						'creds'   => 1,
    						'log'     => '%plural% for someone favorited your forum topic'
    					)
    				)
    			), $hook_prefs );
    		}
    
    		public function run() {
    			add_action( 'bbp_add_user_favorite',  array( $this, 'fav_topic' ) );
    		}
    
    		/**
    		 * Check if the user qualifies for points
    		 */
    		public function fav_topic( $user_id, $topic_id ) {
    			// $user_id is loggedin_user, not author
    
    			// get topic author
    			$topic_author = get_post_field( 'post_author', $topic_id );
    
    			// Check if user is excluded (required)
    			if ( $this->core->exclude_user( $topic_author ) ) return;
    
    			// Make sure this is a unique event
    			if ( $this->has_entry( 'topic_favorited', $topic_id, $topic_author ) ) return;
    
    			// Execute
    			$this->core->add_creds(
    				'topic_favorited',
    				$topic_author,
    				$this->prefs['fav_topic']['creds'],
    				$this->prefs['fav_topic']['log'],
    				$topic_id
    			);
    
    			// Clean up
    			//unset( $this );
    		}
    
    		/**
    		 * Add Settings
    		 */
    		 public function preferences() {
    			// Our settings are available under $this->prefs
    			$prefs = $this->prefs; ?>
    
    	<!-- First we set the amount -->
    	<label class="subheader"><?php echo $this->core->plural(); ?></label>
    	<ol>
    		<li>
    			<div class="h2"><input type="text" name="<?php echo $this->field_name( 'creds' ); ?>" id="<?php echo $this->field_id( 'creds' ); ?>" value="<?php echo $this->core->format_number( $prefs['creds'] ); ?>" size="8" /></div>
    		</li>
    	</ol>
    	<!-- Then the log template -->
    	<label class="subheader"><?php _e( 'Log template', 'mycred' ); ?></label>
    	<ol>
    		<li>
    			<div class="h2"><input type="text" name="<?php echo $this->field_name( 'log' ); ?>" id="<?php echo $this->field_id( 'log' ); ?>" value="<?php echo $prefs['log']; ?>" class="long" /></div>
    		</li>
    	</ol>
    	<?php
    		}
    
    		/**
    		 * Sanitize Preferences
    		 */
    		public function sanitise_preferences( $data ) {
    			$new_data = $data;
    
    			// Apply defaults if any field is left empty
    			$new_data['creds'] = ( !empty( $data['creds'] ) ) ? $data['creds'] : $this->defaults['creds'];
    			$new_data['log'] = ( !empty( $data['log'] ) ) ? sanitize_text_field( $data['log'] ) : $this->defaults['log'];
    
    			return $new_data;
    		}
    	}
    }

    https://www.ads-software.com/extend/plugins/mycred/

Viewing 7 replies - 16 through 22 (of 22 total)
  • Thread Starter Fee

    (@wdfee)

    Yes, that’s it! Now it works ?? !!

    Uhm, is there a function defined by your plugin that checks the data array of the sql table already or do I’ve to start a new query for this question (https://www.ads-software.com/support/topic/points-for-bbpress-topic-author-when-topic-is-favorited?replies=15#post-4324849 above):

    instead of checking for a unique event if ( $this->has_entry( ‘topic_favorited’, $topic_id, $topic_author ) ) return; I’d like to check if the sam user already gave a favorite. Therefore I added the ref_user to the data field. Is there already a function to check it directly? (I saw that you added array( ‘ref_type’ => ‘post’ ) for the bbpress new_topic, so I had this idea to put the ref_user in here in my function)

    Plugin Author myCred

    (@designbymerovingi)

    Yay!

    When it comes to the data variable, yes, the default array is added to indicate that this template tag uses “post related” template tags. You can add to this array like with any other associative array.

    Example:

    array( 'ref_type' => 'post', 'some_key' => 'some_value', 'another_key' => 'more_values' )

    Now, when an array is used in the data variable, myCRED will serialize this before inserting it to the database. So searching for values inside a serialized array can be tricky.

    IF, you know you will only have these two values in your data array (ref_type and your own custom key) then the following custom function will allow you to search for it:

    function my_custom_has_entry_check( $action = '', $ref_id = '', $user_id = '', $data = '' ) {
    	global $wpdb;
    
    	$where = $prep = array();
    	if ( !empty( $action ) ) {
    		$where[] = 'ref = %s';
    		$prep[] = $action;
    	}
    
    	if ( !empty( $ref_id ) ) {
    		$where[] = 'ref_id = %d';
    		$prep[] = $ref_id;
    	}
    
    	if ( !empty( $user_id ) ) {
    		$where[] = 'user_id = %d';
    		$prep[] = abs( $user_id );
    	}
    
    	if ( !empty( $data ) ) {
    		$where[] = 'data = %s';
    		$prep[] = '%' . trim( $data ) . '%';
    	}
    
    	$where = implode( ' AND ', $where );
    
    	if ( !empty( $where ) ) {
    		$sql = "SELECT * FROM " . $wpdb->prefix . 'myCRED_log' . " WHERE $where";
    		$wpdb->get_results( $wpdb->prepare( $sql, $prep ) );
    		if ( $wpdb->num_rows > 0 ) return true;
    	}
    
    	return false;
    }

    NOTE! This function will search your data with the use of wildcards. This means that if you at a later point add more to the data array, lets say another value that also contains a numeric value, then you might run in into getting false positives!

    Hope it makes sense.

    Thread Starter Fee

    (@wdfee)

    ok, your’re great ?? thanks!
    I changed this line:
    $prep[] = '%' . trim( $data ) . '%';
    to
    $prep[] = maybe_serialize($data);
    I think it’s a BuddyPress function, but my theme is a BuddyPress theme, so it’s ok. Now I can use more items in an array, if I want. It just has to be the same in the entry and the same in the has_entry_check. So this is the complete function now (if anybody else is looking for it…):

    public function fav_topic( $user_id, $topic_id ) {
    
    			// $user_id is loggedin_user, not author, so get topic author
    			$topic_author = get_post_field( 'post_author', $topic_id );
    
    			// Check if user is excluded (required)
    			if ( $this->core->exclude_user( $topic_author ) || $topic_author == $user_id  ) return;
    
    			// Make sure this is a unique event (favorite not from same user)
    			if( my_custom_has_entry_check( 'topic_favorited', $topic_id, $topic_author, array('ref_user' => $user_id) ) ) return;
    
    			// Execute
    			$this->core->add_creds(
    				'topic_favorited',
    				$topic_author,
    				$this->prefs['topic_fav']['creds'],
    				$this->prefs['topic_fav']['log'],
    				$topic_id,
    				array( 'ref_user' => $user_id )
    			);
    
    			// Clean up
    			//unset( $this );
    		}
    Plugin Author myCred

    (@designbymerovingi)

    Makes sense, nicely done and great work on your first myCRED Custom Hook!

    Let me know if you have any further issues otherwise Ill mark this topic “Resolved”.

    Plugin Author myCred

    (@designbymerovingi)

    I have added this in 1.1.1.

    Thread Starter Fee

    (@wdfee)

    Hey Gabriel, that’s nice, thanks ??
    Just one hint:
    maybe_serialize makes serialized data out of arrays, so it’s correct to pass the array to it array('ref_user' => $user_id)
    and is a WordPress function (I was wrong with saying, it’s BuddyPress). So you don’t need to pass serialized data as string like ‘s:8:”ref_user”;i:’ . $user_id . ‘;’
    The function makes it automatically looking like this in the sql query. Personally I think it’s more beautiful to use an array.

    Plugin Author myCred

    (@designbymerovingi)

    Hey Fee.

    Yeah, I use maybe_serialize in the has_entry() method.
    If we are to just pass on an array there then i think we will need to add some wildcards around the maybe_serialize since the new data array no longer contains only the ref_user but also the ref_type (to enable user related template tags).

Viewing 7 replies - 16 through 22 (of 22 total)
  • The topic ‘Points for bbPress topic author when topic is favorited’ is closed to new replies.