![]() |
|
Snippets |
|
In the template where the object that users can vote on (here, a snippet) is displayed, add:
<?php echo use_helper('Javascript') ?> <?php $id = $snippet->getId() ?> <?php if($sf_user->canVoteFor($snippet)): ?> <span id="vote_for_<?php echo $id ?>" style="white-space:nowrap;"> rate this snippet: <?php for($i = 1 ; $i <= 5 ; $i++): ?><div class="rate <?php if($i <= $snippet->getAverageVote()): ?>rated<?php endif; ?>" id="vote_<?php echo $id ?>_<?php echo $i ?>"><?php echo link_to_remote(image_tag('spacer.gif', 'width=10 height=10'), array( 'url' => 'snippet/voteForSnippet?id='.$id.'&vote='.$i, 'update' => 'vote_for_'.$id, 'loading' => visual_effect('appear', 'indicator'), 'complete' => visual_effect('fade', 'indicator').visual_effect('highlight', 'vote_for_'.$id), ), array( 'onMouseOver' => 'highlight_stars('.$id.', '.$i.', true);', 'onMouseOut' => 'highlight_stars('.$id.', '.$i.', false);', )) ?></div><?php endfor; ?> <span id="indicator" style="display:none"> <?php echo image_tag('indicator.gif') ?></span> </span> <?php else: ?> <?php include_partial('voted', array('id' => $id, 'vote' => $snippet->getAverageVote())) ?> <?php endif; ?>
Of course, you have to define the rules about who can vote on what in the ->canVoteFor() method of the User object (in apps/myapp/lib/myUser.php).
The template uses a _voted.php partial:
<?php for($i = 1 ; $i <= 5 ; $i++): ?><div class="rate <?php if($i <= $vote): ?>rated<?php endif; ?>" id="vote_<?php echo $id ?>_<?php echo $i ?>"><img src="/images/spacer.gif" width="10" height="10" /></div><?php endfor; ?>
DO NOT add extra spaces to the long lines, or the stars get separated by blank spaces.
The mechanism that changes the aspect of stars relies on classes, so add the following styling to a CSS used in your template:
.rate { display:inline; width:10px; height:10px; margin:0; padding:0; background-image:url(/images/vote_star.gif); background-position: left 10px; } .rated { background-position: left 0px; } .ratehover { background-position: left 20px; }
The vote_star.gif file is a 10x30px image containing three versions of the star: voted, hovered, not voted.

The snippet/voteForSnippet action does something like:
public function executeVoteForSnippet() { $this->id = $this->getRequestParameter('id'); $snippet = SnippetPeer::retrieveByPk($this->id); if(!$snippet) { return sfView::NONE; } $vote = new Vote(); $vote->setUserId($this->getUser()->getUserId()); $vote->setSnippetId($snippet->getId()); $vote->setVote($this->getRequestParameter('vote')); $vote->save(); $this->vote = $vote->getSnippet()->getAverageVote(); }
Comments on this snippet
Just to make things easier for someone trying to replicate this, the schema for this table should look something like this, going along with the snippets theme:
<table name="votes" phpName="Vote"> <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" /> <column name="user_id" type="integer" /> <foreign-key foreignTable="users"> <reference local="user_id" foreign="id" /> </foreign-key> <column name="snippet_id" type="integer" /> <foreign-key foreignTable="snippets"> <reference local="snippet_id" foreign="id" /> </foreign-key> <column name="vote" type="integer" /> <column name="created_at" type="timestamp" /> </table>
And nice job with this... I'm in the process of adapting it for myself. :-)
if some one looking for the "function highlight_stars(id, note, do_highlight) { for (var i = 1 ; i <= note ; i++) { if(do_highlight) Element.addClassName($('vote_' + id + '' + i), 'ratehover'); else Element.removeClassName($('vote' + id + '_' + i), 'ratehover'); } }"
Or, with syntax highlighting:
u;re comment system is messy
nice snippet... thx
thanks