Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#16 2008-03-31 16:59:24

jm
Plugin Author
From: Missoula, MT
Registered: 2005-11-27
Posts: 1,746
Website

Re: jmd_rate: A CSS star rater

Oops, I forgot to fix the link – the star image is here. For the HTML output, you’ll get a raw list if you don’t have any CSS linked to it.

  1. Head to Extensions>jmd_rate and create your CSS. Enter the path to your star image (or hotlink mine)
  2. Place the CSS in a CSS file
  3. Link to it in your head

For the rating, are you redirected to /page?rating=1 (and then to /page)?

Last edited by jm (2008-03-31 16:59:44)

Offline

#17 2008-03-31 23:31:55

lozmatic
Member
From: Melbourne, Australia
Registered: 2006-08-27
Posts: 259
Website

Re: jmd_rate: A CSS star rater

Got most of it working but the display of the current score doesn’t seem to work.

Also, i think the CSS conflicts with my extensive use of CSS for layout. I can’t place things where I want them to be.

I’ll give it a go when I have more time.

Thanks.

Last edited by lozmatic (2008-03-31 23:33:02)

Offline

#18 2008-04-01 00:17:32

jm
Plugin Author
From: Missoula, MT
Registered: 2005-11-27
Posts: 1,746
Website

Re: jmd_rate: A CSS star rater

That is strange – you should have <li class="current_rating" style="width: Xpx;">Currently rated Y</li> immediately after the ul in your source code. I’ll see if I can replicate it – can you post the jmd_rate section from your template?

Off topic: Any reason for using a span to wrap a ul? Might want to close some of those tags too :).

Offline

#19 2008-04-01 01:12:45

lozmatic
Member
From: Melbourne, Australia
Registered: 2006-08-27
Posts: 259
Website

Re: jmd_rate: A CSS star rater

ah, i got rid of the ‘Currently rated’ bit because i wanted to have the stars fit nicely next to the page’s title.

Yeah, it’s all a bot messy there. I tried wrapping things in nasty nasty ways to try and position the stars.

Offline

#20 2008-04-01 01:28:12

jm
Plugin Author
From: Missoula, MT
Registered: 2005-11-27
Posts: 1,746
Website

Re: jmd_rate: A CSS star rater

Tsk, tsk! The li[class=current_rating] is responsible for the current score display (half-filled stars, etc). If the CSS and HTML is correct (and not too invalid), it’ll draw the stars and not display the text (text-indent: -9999px). I suggest grabbing a new copy of the plugin :).

Offline

#21 2008-04-01 01:42:08

lozmatic
Member
From: Melbourne, Australia
Registered: 2006-08-27
Posts: 259
Website

Re: jmd_rate: A CSS star rater

I seek forgivness…

Offline

#22 2008-04-01 02:30:40

lozmatic
Member
From: Melbourne, Australia
Registered: 2006-08-27
Posts: 259
Website

Re: jmd_rate: A CSS star rater

Ok, now it works wonderfully and beautifully – i’ve positioned elements exactly where I want them.

Thanks.

Offline

#23 2008-04-01 03:32:44

jm
Plugin Author
From: Missoula, MT
Registered: 2005-11-27
Posts: 1,746
Website

Re: jmd_rate: A CSS star rater

Cool – glad you got it working.

I’m planning on adding read-only display (for jmd_rate_article and jmd_article_cf use) next (probably this week), then I’ll work on Ajax (this weekend?).

Offline

#24 2008-04-01 21:15:23

lozmatic
Member
From: Melbourne, Australia
Registered: 2006-08-27
Posts: 259
Website

Re: jmd_rate: A CSS star rater

Cool, well, as is… it’s very cool.

One thing I’ve noticed, though. When I rate using firefox the new rating only displays when I click shift and the refresh button. Until I do that I can continue voting… is this the case with anyone else?

Offline

#25 2008-04-01 21:33:02

jm
Plugin Author
From: Missoula, MT
Registered: 2005-11-27
Posts: 1,746
Website

Re: jmd_rate: A CSS star rater

Strange – does it happen to you here too?

  1. Does the page redirect at all? My votes are already recorded, so I couldn’t test the site (I don’t remember it hanging). Could you head to Extensions>jmd_rate and uninstall then install it?
  2. Is PHP under fast-cgi or installed as an Apache module?

Offline

#26 2008-04-02 10:15:37

lozmatic
Member
From: Melbourne, Australia
Registered: 2006-08-27
Posts: 259
Website

Re: jmd_rate: A CSS star rater

Yes, and I’ve just tested using my work PC that has a different version of FireFox (and a different connnection).

To answer your questions…

1. The page seems to load up again after clicking to vote
2. Not quite sure. How can I check this… in txp or on my server?

Offline

#27 2008-04-08 03:34:31

nardo
Member
From: tuvalahiti
Registered: 2004-04-22
Posts: 743

Re: jmd_rate: A CSS star rater

for a review site … would it be possible for the article author to add a star rating, and each commenter to add a star rating… and their personal ratings were displayed beside their name… but also the total user rating was displayed in a sidebox?

Offline

#28 2008-04-08 06:33:58

jm
Plugin Author
From: Missoula, MT
Registered: 2005-11-27
Posts: 1,746
Website

Re: jmd_rate: A CSS star rater

lozmatic wrote:

  1. The page seems to load up again after clicking to vote
  2. Not quite sure. How can I check this… in txp or on my server?

  1. Strange. I’m having a hard time replicating the bug (I’ve experienced it though). Could you post your jmd_rate code from your article form?
  2. Admin>Diagnostics: High – if you see something like “PHP Server API: cgi” or “mod_fastcgi” anywhere, you’re running fastcgi. The first two versions had a header redirect bug I though I’d solved, at least for my server.

nardo wrote:

for a review site … would it be possible for the article author to add a star rating, and each commenter to add a star rating… and their personal ratings were displayed beside their name… but also the total user rating was displayed in a sidebox?

I think it would be, but I haven’t had a chance to work with comments yet. For the article author rating, it could be done with a custom field (“author_rating”) and a small amount of PHP – something like:

<txp:php>
// number of stars
$stars = 5;
// width of stars
$starWidth = 30;
// width of the ul
$ulWidth = ($stars * $starWidth);
// custom field name == author_rating
$authorRating = custom_field(array(
	'name' => 'author_rating'
));
$rating = ($stars/$authorRating);
// rating width
$ratingWidth = ($rating * $starWidth);

// HTML output
echo '<ul class="rating" style="width: '. $ulWidth .'px">
	<li style="width: '. $ratingWidth .'px" id="current_rating">
		'. $rating .'
	</li>
</ul>';
</txp:php>

OK, so that’s probably enough PHP to be added to the plugin. YAVT: <txp:jmd_rate_author_rating/>

Last edited by jm (2008-04-08 06:47:06)

Offline

#29 2008-04-08 08:47:23

lozmatic
Member
From: Melbourne, Australia
Registered: 2006-08-27
Posts: 259
Website

Re: jmd_rate: A CSS star rater

Hi,

Would this be it?

PHP Server API: cgi-fcgi

Code is…

--------------------------------------
// admin

if (@txpinterface == 'admin')
{
	add_privs('jmd_rate_prefs', '1');
	register_tab('extensions', 'jmd_rate_prefs', 'jmd_rate');
	register_callback('jmd_rate_prefs', 'jmd_rate_prefs');
}

function jmd_rate_prefs($event, $step)
{
	ob_start('jmd_rate_prefs_head');
	pagetop('jmd_rate_prefs');
	echo '<div id="jmd_rate_prefs">';

	if (!$step)
	{
		echo fieldset(
			form(
				(
					fInput('submit', 'install', 'Install', 'publish').
					eInput('jmd_rate_prefs').
					sInput('install')
				)
			).
			form(
				(
					fInput('submit', 'uninstall', 'Uninstall', 'publish').
					eInput('jmd_rate_prefs').
					sInput('uninstall')
				), '', "verify('Are you sure you want to delete all ratings?');"
			), 'Setup', 'setup'
		);
		echo fieldset(
			form(
				'<label>Quantity '.fInput('text', 'qty', 4).'</label><br/>
				<label>Path and filename of star image '.fInput('text', 'path', '/stars.png').'</label><br/>
				<label>Star width'.fInput('text', 'width', 19).'</label><br/>
				<label>Star height'.fInput('text', 'height', 18).'</label><br/>
				<label>Container class name'.fInput('text', 'class', 'rating').'</label><br/>'.
				fInput('submit', 'generate', 'Generate CSS', 'publish').
				eInput('jmd_rate_prefs').
				sInput('builder')
			), 'CSS builder'
		);
	}
	elseif ($step == 'install')
	{
		$sql = "CREATE TABLE ".safe_pfx('jmd_rate')."(
			parentid INT,
			value INT,
			max_value INT,
			ip INT UNSIGNED,
			PRIMARY KEY(parentid, ip)
		)";
		$create = safe_query($sql);
		if ($create)
		{
			echo tag('Table created successfully. '.eLink('jmd_rate_prefs', '', '', '', 'Back to preferences?'), 'p', ' class="ok"');
		}
		else
		{
			echo tag('Database exists. '.eLink('jmd_rate_prefs', '', '', '', 'Back to preferences?'), 'p', ' class="not-ok"');
		}
	}
	elseif ($step == 'uninstall')
	{
		safe_query("DROP TABLE IF EXISTS ".safe_pfx('jmd_rate'));
		echo tag('Table dropped. '.eLink('jmd_rate_prefs', '', '', '', 'Back to preferences?'), 'p', ' class="ok"');
	}
	elseif ($step == 'builder')
	{
		if (is_numeric(gps('qty')) && is_numeric(gps('width')) && is_numeric(gps('height')))
		{
			$qty = gps('qty');
			$w = round(gps('width'));
			$h = round(gps('height'));
			$path = htmlentities(gps('path'));
			$class = '.'.gps('class');

			echo tag('CSS', 'h1');
			echo "
<textarea class=\"code\" cols=\"78\" rows=\"32\" id=\"jmd_rate_css\">
$class {}
	$class, $class * {
		margin: 0;
		border: 0;
		padding: 0;
	}
	$class ul {
		height: ".$h."px;
		position: relative;
	}
		$class ul, $class .current_rating, $class a:hover {
			background: url($path);
		}
		$class li {
			list-style: none;
			text-indent: -9999px;
		}
			$class .current_rating {
				background-position: 0 -".$h."px;
				z-index: 1;
			}
				$class .current_rating, $class a {
					height: ".$h."px;
					position: absolute;
					top: 0;
					left: 0;
				}
			$class a {
				width: ".$w."px;
				height: ".$h."px;
				overflow: hidden;
				z-index: 3;
			}
				$class a:hover{
					background-position: left center;
					left: 0;
					z-index: 2;
				}
					".$class."_1 a:hover { width: ".$w."px }
			";
			for ($i = 2; $i <= $qty; $i++)
			{
				echo '
					'.$class.'_'.$i.' a { left: '.($i - 1) * $w.'px }
					'.$class.'_'.$i.' a:hover { width: '.$w * $i.'px }
				';
			}
			echo '</textarea>';
		}
		echo tag(eLink('jmd_rate_prefs', '', '', '', 'Try again?'), 'p');
	}
	else
	{
		echo tag('Error.', 'h1');
	}
	echo '</div><!--//jmd_rate_prefs-->';
}

// courtesy of upm_savenew <http://utterplush.com/txp-plugins/upm-savenew>
function jmd_rate_prefs_head($buffer)
{
	$find = '</head>';
	$replace = '
		<script type="text/javascript">
		function jmd_rate() {
			var input = document.getElementById("jmd_rate_prefs").getElementsByTagName("input");
			for (i = 0; i < input.length; i++) {
				if (input[i].getAttribute("type") == "text") {
					input[i].onfocus = function() {
						this.select();
					};
				}
			}
			var cssOutput = document.getElementById("jmd_rate_css");
			if (cssOutput) {
				cssOutput.onclick = function() {
					this.select();
				};
			}

		}
		addEvent(window, "load", jmd_rate);
		</script>
		<style type="text/css">
			#jmd_rate_prefs {
				width: 500px;
				margin: 20px auto;
			}
			fieldset label {
				display: block;
			}
		 	#setup form {
				display: inline;
			}
			p.not-ok {
				margin-top: 10px;
			}
		</style>
	';

	return str_replace($find, $replace.$find, $buffer);
}


//--------------------------------------
// public

// instantiates jmd_rate class
function jmd_rate($atts, $thing)
{
	extract(lAtts(array(
		'class' => 'rating',
		'stars' => 4,
		'star_width' => 19,
		'wraptag' => 'div',
	), $atts));

	global $jmd_rate_instance;
	$jmd_rate_instance = new jmd_rate($stars, $star_width);
	$out = $jmd_rate_instance->getRating().parse($thing);

	return ($wraptag) ? doTag($out, $wraptag, $class) : $out;
}

// displays rater
function jmd_rate_display($atts)
{
	return $GLOBALS['jmd_rate_instance']->display();
}

// checks for votes
function if_jmd_rate_votes($atts, $thing)
{
	$condition = ($GLOBALS['jmd_rate_instance']->votes > 0);
	$out = EvalElse($thing, $condition);

	return parse($out);
}

// Max rating possible
function jmd_rate_max($atts)
{
	return $GLOBALS['jmd_rate_instance']->maxValue;
}

// returns current rating
function jmd_rate_rating($atts)
{
	return $GLOBALS['jmd_rate_instance']->rating;
}

// returns number of votes
function jmd_rate_votes($atts)
{
	extract(lAtts(array(
		'singular' => '',
		'plural' => '',
	), $atts));
	$votes = $GLOBALS['jmd_rate_instance']->votes;
	$out = $votes.' ';

	if ($singular && $plural)
	{
        $out .= (($votes > 1) ? $plural : $singular);
	}

	return $out;
}

// checks if the user has voted
function if_jmd_rate_voted($atts, $thing)
{
	$condition = $GLOBALS['jmd_rate_instance']->voted;
	$out = EvalElse($thing, $condition);

	return parse($out);
}

// article_custom with sort by rating
function jmd_rate_article($atts)
{
	extract(lAtts(array(
		'author'     => '',
		'category'   => '',
		'form'       => 'default',
		'keywords'   => '',
		'limit'      => '10',
		'max_rating' => '',
		'min_rating' => '',
		'month'      => '',
		'section'    => '',
		'sort'       => 'DESC',
	), $atts));

	$matching = getRows("SELECT parentid, avg(value) AS rating FROM ".safe_pfx('jmd_rate')." GROUP BY parentid HAVING rating BETWEEN $min_rating and $max_rating ORDER BY rating $sort LIMIT $limit");
	// if no articles match the criteria, exit
	if (!$matching)
	{
		return;
	}
	$out = '';
	foreach ($matching as $article)
	{
		$out .= article_custom(array(
			'author'    => $author,
			'category'  => $category,
			'form'      => $form,
			'id'        => $article['parentid'],
			'keywords'  => $keywords,
			'limit'     => $limit,
			'month'     => $month,
			'section'   => $section,
		));
	}

	return $out;
}


class jmd_rate
{
	// input
	private $starWidth;
	public $maxValue;
	// helpers
	private $dbTable, $parentid, $ip, $uri;
	// rating
	private $value, $usedIps;
	public $votes, $voted, $rating;

	public function __construct($stars, $star_width)
	{
		ob_start();
		$this->dbTable = 'jmd_rate';
		$this->parentid = $GLOBALS['thisarticle']['thisid'];
		$this->uri = permlinkurl_id($this->parentid);
		$this->ip = $_SERVER['REMOTE_ADDR'];

		$this->maxValue = $stars;
		$this->starWidth = $star_width;

		if (gps('rating'))
		{
			$this->setRating();
		}
	}

	public function getRating()
	{
		$query = "SELECT sum(value) AS total_value, count(value) AS total_votes, max_value FROM ".safe_pfx($this->dbTable)." WHERE parentid=$this->parentid GROUP BY max_value";
		$row = getRows($query);

		// if the query was empty, exit
		if (!$row)
		{
			return;
		}

		foreach($row as $r)
		{
			extract($r);
	 	}

		$this->value = $r['total_value'];
		$this->votes = $r['total_votes'];

		// if the # of stars has changed, adjust previous votes
		if ($r['max_value'] != $this->maxValue)
		{
			$scalar = ($this->maxValue/$r['max_value']);
			// adjust display value
			$this->value *= $scalar;
			// adjust previous votes
			safe_update($this->dbTable, "value=(value*$scalar), max_value=$this->maxValue", "parentid=$this->parentid");
		}

		$this->rating = @number_format($this->value/$this->votes, 2);

		// see if the visitor has voted
		$this->voted = safe_field("ip", $this->dbTable, "ip=INET_ATON('$this->ip') AND parentid=$this->parentid");
	}

	private function setRating()
	{
		$userRating = intval(gps('rating'));
		if ($this->voted)
		{
			echo tag('You have already voted!', 'p', ' class="error"');
		}
		elseif ($userRating > $this->maxValue)
		{
			echo tag('Cheater!', 'p', ' class="error"');
		}
		else
		{
			safe_insert($this->dbTable, "parentid=$this->parentid, value=$userRating, max_value=$this->maxValue, ip=INET_ATON('$this->ip')");
            // redirect - thanks to zem_contact_reborn
			while (@ob_end_clean());
            txp_status_header('303 See Other');
			header('Location: '.$this->uri);
		}
	}

	public function display()
	{
		$out = '<ul style="width: '.$this->maxValue * $this->starWidth.'px">';
		$out .= '<li class="current_rating" style="width: '.$this->rating * $this->starWidth.'px;">Currently rated '.$this->rating.'</li>';

		// if they haven't voted and voting is open, link the stars
		if (!$this->voted)
		{
			$getUri = ($GLOBALS['permlink_mode'] == 'messy') ? '&amp;rating=' : '?rating=';
			for ($i = 1; $i <= $this->maxValue; $i++)
			{
				$out .= '<li class="rating_'.$i.'">
					<a href="'.$this->uri.$getUri.$i.'" rel="nofollow">
						'.$i.'/'.$this->maxValue.'
					</a>
				</li>';
			}
		}
		$out .= '</ul>';

		return $out;
	}
}@

Offline

#30 2008-04-14 15:07:25

bluemonkay
New Member
Registered: 2004-08-12
Posts: 2

Re: jmd_rate: A CSS star rater

love the plugin, i’m looking at using it on a departmental intranet.

however we are all stuck on the same ip and so i get to rate and nobody else is able- does anybody know of a way to hack out the ip checking or a way of allowing the same ip to vote multiple ways.

in a perfect world for my use i’d base it on cookies and not ip, sadly my skils aren’t up to the job.

still i love the customisation elements of this plugin and it’s good to see the community still thriving.

(i’ve been away from txp for a while)

Offline

Board footer

Powered by FluxBB