About this topic

  • Posted by WindupHarlequin 2 months ago. There are 13 posts. The latest reply is from byron.
  1. Well, here's some small changes made to the code to improve the shortcodes available for users. This essentially allows you to use shortcodes to determine a gallery's sorting order and type. The changes are very minimal, however, and could well be improved upon: this is purely to get a working version out, for Byron to adapt (should he so wish).

    Anyways...

    bwbps-layout.php:

    Line 2702: Change to

    $sortorder = $g['sort_order']>0 || strtolower($g['sort_order']) == 'asc' ? "ASC" : "DESC";

    - Sets the order to the correct string, allowing either numerical or string-based parameters. Defaults to 'DESC'.

    Line 2711: Change to

    if( (int)$g['sort_field'] == 4 || $g['sort_field'] == "rank"){

    - Allows correct generation of ranking SQL if sort_field is set to 'rank'. It should really be checking against a value defined elsewhere, to allow you to change the short_code strings independently of the rest of your code.

    Lines 3050: Change to

    switch ( (string)$g['sort_field'] ){
    	case "sequence" :
    	case "1" :	// Custom Sort
    		$sortby = PSIMAGESTABLE.'.seq, '.PSIMAGESTABLE.'.created_date '. $sortorder;
    		break;
    	/* -- Not implemented --
    	case "custom" :
    	case "2" :
    	*/
    	case "user" :
    	case "3" :	// User IDs
    		$sortby = PSIMAGESTABLE.'.user_id ' . $sortorder . ', '.PSIMAGESTABLE.'.seq';
    		break;
    	case "user_name" :
    	case "6" :	// User Name
    		$sortby = $wpdb->users.'.user_nicename ' . $sortorder . ', ' . $wpdb->users.'.user_login ' . $sortorder . ', '.PSIMAGESTABLE.'.seq';
    		break;
    	case "user_login" :
    	case "7" :	// User Login
    		$sortby = $wpdb->users.'.user_login ' . $sortorder . ', ' . $wpdb->users.'.user_nicename ' . $sortorder . ', '.PSIMAGESTABLE.'.seq';
    		break;
    	case "rank" :
    	case "4" :	// Rating
    		switch ((int)$g['poll_id'] ) {
    
    			case -2 :	// Vote up /vote down
    				$sortby = 'bwbps_br_rating '. $sortorder . ', '.PSIMAGESTABLE.'.votes_cnt DESC ';
    				break;
    
    			case -3 :	// Vote up
    				$sortby = 'votes_sum '
    							. $sortorder . ', '.PSIMAGESTABLE.'.votes_cnt ASC, '.PSIMAGESTABLE.'.seq';
    				break;
    
    					// Default to Bayesian sorting
    			default :
    				$sortby = 'bwbps_br_rating '
    							. $sortorder . ', '.PSIMAGESTABLE.'.seq';
    				break;
    			}
    
    			break;
    	case "favourites" :
    	case "5" :	// Favorites Count
    		$sortby = PSIMAGESTABLE.'.favorites_cnt ' . $sortorder . ', '.PSIMAGESTABLE.'.seq';
    		break;
    	// Default to created date
    	default :	// When Uploaded
    		$sortby = PSIMAGESTABLE.'.created_date '
    					. $sortorder . ', '.PSIMAGESTABLE.'.seq';
    		break;
    	}

    - Essentially creates string aliases for each of case conditions. Removed those that are the same as the default conditions, and commented out the custom search, given that that isn't implemented in the latest release version.

    bwb-photosmash.php:

    Line 862: Append with

    'sort_field' => false, // Custom - allows sorting
    	'sort_order' => 0 // Same as above

    - Fairly obviously adds to array of tags to extract from shortcode. Ensure that the 'piclens_class' value is followed with a comma.

    Line 1021: Add

    // Custom - allow specification of sorting
    if(isset($sort_order)) $galparams['sort_order'] = $sort_order;
    if(isset($sort_field)) $galparams['sort_field'] = $sort_field;

    - Once you've done all the default Photosmash behaviour, check to see if we've set the two custom variables, and override any default values generated.

    Lines 1607 & 1609: Replace with

    $data['sort_field'] = isset($data['sort_field']) ? $data['sort_field'] : $this->psOptions['sort_field'];
    
    $data['sort_order'] = isset($data['sort_order']) ? $data['sort_order'] : $this->psOptions['sort_order'];

    - Ensures that we're not typecasting these variables as integers

    ...And that should be that! Try it out yourself by using the shortcode. For instance, "[photosmash id=2 sort_field=rank sort_order=ASC]".

    Hope this proves useful!

  2. Just as an example, I can use this to do Ajax updates and switching of sorting for users. Here's a quick example:

    In my template functions.php file, I add:

    // AJAX controls to allow users to refresh gallery
    add_action('wp_ajax_get_gallery', 'get_gallery');
    add_action('wp_ajax_nopriv_get_gallery', 'get_gallery');
    
    function get_gallery()
    {
    	$sort = isset($_POST['sort']) ? $_POST['sort'] : "created";
    	$order = isset($_POST['order']) ? $_POST['order'] : "DESC";
    
    	// 2 is the magic number, or in other words, the id for our primary gallery
    	$ret = do_shortcode("[photosmash id=2 sort_field=$sort sort_order=$order]");
    	echo $ret;
    	exit;
    }

    This uses the built-in Wordpress AJAX system to get the necessary data - in this case sort field & order - and echo out the results of shortcode parsed with those values.

    In a javascript file for the gallery page, I add the following javascript to trigger the AJAX calls:

    var ajaxurl = "<?php echo admin_url('admin-ajax.php'); ?>";
    var order = Array();
    order['created'] = "asc";
    order['rank'] = "asc";
    
    jQuery("div#content a.gal-sort").click(function() {
    	var name = jQuery(this).attr("id");
    	var data = {
    		action: 'get_gallery',
    		cookie: encodeURIComponent(document.cookie),
    		sort: name,
    		order: order[name]
    	};
    
    	// switch between asc and desc
    	order[name] = (order[name] == 'asc') ? 'desc' : 'asc';
    
    	jQuery.post(ajaxurl, data, function(response) {
    		jQuery("div#gallery").fadeOut('',function() {
    
    			jQuery("div#gallery").html(response);
    			psmash_footer_code();
    			jQuery("div#gallery").fadeIn();
    		});
    	});
    });

    - This sets up the necessary data (here, I'm only switching between Created and Rank - I use the array to keep state between ordering directions) and then assigns a click function, using the a tag's ID as the sort field. When the tag is clicked, it fades out the gallery, then replaces it with the updated html.

    In order to get star ratings added, you'll need to change part of the code in bwb-photosmash.php:
    Lines 2571 - 2576: change to

    $ret .= "
    function psmash_footer_code() { ". $this->footerReady . " };
    // On Document Ready
    jQuery(document).ready(function() {
    	psmash_footer_code();
    }); ";

    - This creates a globally available javascript function for setting up ranking stars, which is called every time the page is refreshed (which obviously returns the base gallery html, without ranking functions applied).

    The basic html that this all works with is simple:

    <a id="created" href="#">Latest</a>
    <a id="rank" href="#">Highest rated</a>
    <div id="gallery" style="float:left; width: 600px;">
    	<?php
    	$ret = do_shortcode("[photosmash id=2 sort_field=created sort_order=desc]");
    	echo $ret;
    ?>
    </div>

    Which just creates the default gallery when page is first loaded.

    Hope this helps :)

  3. First of all, thanks! That's a lot of work.

    That's some very useful functionality. Lots of people have wanted user controlled sorting. One thought that I had was how we might maintain the sorting when moving between Pages for folks who have pagination turned on.

    The use of wp_ajax was new to me...I'd like to use the recommended functionality where possible, and that would appear to be more standard than the way I'm calling Ajax handlers and loading WP from them. So at some point in the code rewrite I'll try to switch to that functionality.

    So, from your perspective, if we can get the code from your first post integrated into the core, that would be a good start?

    I'll take some time to digest this. I really appreciate the contribution!

    BB

  4. Thanks for the feedback :) I would say that you could definitely port the code from the first post over, although I stress that it should be tested. You will undoubtedly have a more comprehensive idea of what functionality to expect as default for the plugin, so please at least test my code in a few example scenarios before releasing it to the public and having it break everyone's gallery :P

    As for your other point, Wordpress has some nice AJAX tools that allow you to hook into any Action that you define. The reason I use

    add_action('wp_ajax_get_gallery', 'get_gallery');
    add_action('wp_ajax_nopriv_get_gallery', 'get_gallery');
    is because by default, Wordpress AJAX can only be called by logged-in users. Adding 'wp_ajax_nopriv_get_gallery' allows anyone to send a request and have the action performed. You can find more information here: http://codex.wordpress.org/AJAX_in_Plugins

    I notice that you don't seem to be using many Actions or Filters in your plugin. That's absolutely fine - there's nothing to say you have to - but for many of the functions you're using to generate user-side HTML, I can't help but wonder if you'd be better off using Filters on your content. But that's a very uninformed opinion, I'd need to look at what you're doing far more closely to be able to say if that's a good idea.

    Anyways, I'm glad this is of some help :) I will continue to let you know if there are changes I feel should be made to the code-base. I'm looking at sorting out your ranking system. At the moment, when sorting by Bayesian rank, any images without votes will have no stars displayed, but still be placed above those with one star. This is because they have a Bayesian average of 2.5 stars, yet this isn't being displayed. Will let you know when I get this working.

    Again, thanks for being so open to comments. So many developers absolutely refuse to let anyone touch their code, it's refreshing to have someone who will listen. I hope the rest of your development goes well!

    - WindupHarlequin

  5. In the current Dev version, I'm starting to use Actions and Filters more. They really are incredibly useful. WP uses them like crazy in the core, and I'm starting get an understanding of why. It does eliminate some IF THEN code by letting a condition set up a call on a fliter/action. It is possible that they could simplify some of the Layout code. This plus MVC should make for a better PhotoSmash 2.0 ;-) Might end up skipping 1.0 altogether :P

    I still haven't had a chance to work through your code here to get it implemented.

    As far as the Pagination issue, the only thing I can think of is to add it to the URL (along with the pagination code) or put it into a Session variable. Do you have an opinion on those 2 options? I haven't played with Session variables in a couple of years (since I was trying to figure out logins with Code Igniter). Would I even have an opportunity to do that if we're bringing back the sorted gallery via Ajax?

    You'd like to think the following could happen:
    1) User opens a page w/ a gallery
    2) User changes the sort order (brings sorted gallery back via Ajax)
    3) Session variable is updated to include the selected sort
    4) User moves to Page 2 and gallery comes back using the selected sort for page 2

    I'm not sure, but your Ajax code may be returning the pagination as well, in which case, I could just add the sort to the pagination URLs and skip the session stuff.

    Thoughts?

    Thanks!
    BB

  6. I would say that the best option is to use session variables to hold your sort, order and pagination variables.

    So, for instance, in your function that's being called by the action, it would look something like:

    function get_gallery()
    {
    	$sort = isset($_POST['sort']) ? $_POST['sort'] : "created";
    	$order = isset($_POST['order']) ? $_POST['order'] : "DESC";
    
    	$_SESSION['sort'] = $sort;
    	$_SESSION['order'] = $order;
    
    	// 2 is the magic number, or in other words, the id for our primary gallery
    	$ret = do_shortcode("[photosmash id=2 sort_field=$sort sort_order=$order]");
    	echo $ret;
    	exit;
    }

    Now, the thing with that is that it'll constantly reset to the first page, so you'll need to add to the javascript:

    var data = {
    		action: 'get_gallery',
    		cookie: encodeURIComponent(document.cookie),
    		sort: name,
    		order: order[name]
    		<? if($page = $_GET['bwbps_page_6']) echo ", page: $page"; ?>
    	};

    With the get_gallery function updated to make use of that with the shortcode.

  7. Actually, I suspect there may be more to it than that - I haven't personally played around with pagination yet, although I probably should (given that I'll need to implement it for a commercial project soon... :P )

    From what I see, the plugin is looking to see if there's a GET variable containing the photosmash page number. This won't be submitted when you do the AJAX call, at least, not as I've written it.

    However... it might, concievably, work if you do the following with the javascript:

    var data = {
    		action: 'get_gallery',
    		cookie: encodeURIComponent(document.cookie),
    		sort: name,
    		order: order[name]
    		<? if($page  = $_GET['bwbps_page_6']) echo ", bwbps_page_6: $page"; ?>
    	};
    
    	// switch between asc and desc
    	order[name] = (order[name] == 'asc') ? 'desc' : 'asc';
    
    	jQuery.get(ajaxurl, data, function(response) {
    
    		....

    This means that the AJAX request will have the pagination GET variable accesible to it... so... I guess you'll have to try it out and see.

    - WindupHarlequin

  8. Hi WUH,

    I've been working on adding the sorting code, and think I've got it there. Check out the Changelog ( http://smashly.net/photosmash-galleries/change-log/ ) for 0.7.04 to see what's been added for sorting purposes. I'm loading this to the development version on WP ASAP, so if you can take a test, that'd be helpful.

    Also, note that I've gone with the American spelling of favorites, with all due respect to the Queen's English.

    I did encounter a problem with this little bit of code you mentioned: if($image['bwbps_br_rating']) $rating['avg_rating'] = $image['bwbps_br_rating'];

    It turns out that if you have only one or no votes, it gets whacky...no votes actually shows a value of .8 (in my case, maybe different depending on the total # of votes). I'm open to suggestions on that.

  9. Development version for 0.7.04 is now out in the development version on WordPress. Please take a look if you get a chance.

  10. Hi Byron. I notice you've pushed out a new 0.8 release - good work! I'm looking forward to seeing the changes you've made. As you said in the other thread, there's clearly an issue with the Bayesian rating when it has a small (or non-existent) amount of votes - I'll look into it hopefully next week.

    Let me know if there's anything else you'd like a second opinion on :)

    - WindupHarlequin

  11. Thanks! Yep, that was the problem...when few # of images with low votes, you get some weird ratings. I had a couple of things that could stand some additional thinkers:

    1) At the end of that last dev cycle, I spent a lot of time trying to reduce the # of queries that PhotoSmash generates. I was able to remove maybe 1 or 2, but can probably squeeze out another or so. One thing I was considering is to include the list of custom fields (and standard fields) that are used in Custom Layouts and Custom Forms.

    2) And on this point, I'm thinking about converting the algo for processing the Standard Layout to use the same algo as a Custom Layout, which would entail having a layout for the standard layout that gets modified at runtime to account for Gallery and Shortcode options that affect the std layout display. I think this will make it much more standardized and open up some new possibilities to have them all processed the same.

    3) I'm thinking that it might be pretty powerful to provide a tag for Layouts and Forms that can process a shortcode...something like: [shortcode code='{...}']

  12. Funnily enough, I am literally just working through a way that I could convert your Custom Forms to be compatible with shortcodes. The design I'm working with requires a certain amount of integration with other content stored in Wordpress, and so I'm thinking of ways to allow PHP code to operate. I think that shortcodes for custom forms shouldn't be too difficult, tbh - you pretty much have it set up anyway with your custom-form editor, so I'll let you know how I get on with transplanting that.

    Having the Standard Layout using the same algorithm as is used for Custom Layouts is a great idea. Create a generic Layout class, with methods for adding fields and generating HTML. It'll not only cut down on the code, and probably eliminate some redundant queries / functions, but it also means that if you find you need to add functionality to Custom Layouts to recreate the standard layout, then all your users will benefit.

    I'll get back to you in a bit once I've had a good look at your layout engine. Hope to add something useful soon!

    - WindupHarlequin

  13. Excellent! I think the shortcode route would be much safer than the exec() route. It controls exactly which functions are available.

    The current layouts class is messy and got messsier with this last revision. I think the idea works pretty well, but I need to do a do-over.

    I'm looking forward to seeing what you come up with.

    BB

RSS feed for this topic

Reply

You must log in to post.