- image rating on picture page done through ajax (tested safari/ie 6&7/ff)

git-svn-id: http://piwigo.org/svn/trunk@2435 68402e56-0260-453c-a942-63ccdbb3a9ee
This commit is contained in:
rvelices 2008-07-15 01:29:23 +00:00
commit 9c96b905ff
5 changed files with 136 additions and 77 deletions

View file

@ -36,14 +36,14 @@ function rate_picture($image_id, $rate)
or !$conf['rate'] or !$conf['rate']
or !in_array($rate, $conf['rate_items'])) or !in_array($rate, $conf['rate_items']))
{ {
return; return false;
} }
$user_anonymous = is_autorize_status(ACCESS_CLASSIC) ? false : true; $user_anonymous = is_autorize_status(ACCESS_CLASSIC) ? false : true;
if ($user_anonymous and !$conf['rate_anonymous']) if ($user_anonymous and !$conf['rate_anonymous'])
{ {
return; return false;
} }
$ip_components = explode('.', $_SERVER["REMOTE_ADDR"]); $ip_components = explode('.', $_SERVER["REMOTE_ADDR"]);
@ -118,17 +118,20 @@ INSERT
// update of images.average_rate field // update of images.average_rate field
$query = ' $query = '
SELECT ROUND(AVG(rate),2) AS average_rate SELECT COUNT(rate) AS count
, ROUND(AVG(rate),2) AS average
, ROUND(STD(rate),2) AS stdev
FROM '.RATE_TABLE.' FROM '.RATE_TABLE.'
WHERE element_id = '.$image_id.' WHERE element_id = '.$image_id.'
;'; ;';
$row = mysql_fetch_array(pwg_query($query)); $row = mysql_fetch_assoc(pwg_query($query));
$query = ' $query = '
UPDATE '.IMAGES_TABLE.' UPDATE '.IMAGES_TABLE.'
SET average_rate = '.$row['average_rate'].' SET average_rate = '.$row['average'].'
WHERE id = '.$image_id.' WHERE id = '.$image_id.'
;'; ;';
pwg_query($query); pwg_query($query);
return $row;
} }
?> ?>

View file

@ -775,6 +775,41 @@ SELECT id, date, author, content
return new PwgNamedStruct('image',$ret, null, array('name','comment') ); return new PwgNamedStruct('image',$ret, null, array('name','comment') );
} }
/**
* rates the image_id in the parameter
*/
function ws_images_Rate($params, &$service)
{
$image_id = (int)$params['image_id'];
$query = '
SELECT DISTINCT id FROM '.IMAGES_TABLE.'
INNER JOIN '.IMAGE_CATEGORY_TABLE.' ON id=image_id
WHERE id='.$image_id
.get_sql_condition_FandF(
array(
'forbidden_categories' => 'category_id',
'forbidden_images' => 'id',
),
' AND'
).'
LIMIT 1';
if ( mysql_num_rows( pwg_query($query) )==0 )
{
return new PwgError(404, "Invalid image_id or access denied" );
}
$rate = (int)$params['rate'];
include_once(PHPWG_ROOT_PATH.'include/functions_rate.inc.php');
$res = rate_picture( $image_id, $rate );
if ($res==false)
{
global $conf;
return new PwgError( 403, "Forbidden or rate not in ". implode(',',$conf['rate_items']));
}
return $res;
}
/** /**
* returns a list of elements corresponding to a query search * returns a list of elements corresponding to a query search
*/ */

View file

@ -162,7 +162,6 @@ y.callService(
{ {
selectElement.disabled = true; selectElement.disabled = true;
var y = new PwgWS(rootUrl); var y = new PwgWS(rootUrl);
y.callService( y.callService(
"pwg.images.setPrivacyLevel", {image_id: id, level:level} , "pwg.images.setPrivacyLevel", {image_id: id, level:level} ,
{ {
@ -182,7 +181,7 @@ y.callService(
{if isset($rate_summary) } {if isset($rate_summary) }
<tr> <tr>
<td class="label">{'Average rate'|@translate}</td> <td class="label">{'Average rate'|@translate}</td>
<td class="value"> <td class="value" id="ratingSummary">
{if $rate_summary.count} {if $rate_summary.count}
{assign var='rate_text' value='%.2f (rated %d times, standard deviation = %.2f)'|@translate } {assign var='rate_text' value='%.2f (rated %d times, standard deviation = %.2f)'|@translate }
{$pwg->sprintf($rate_text, $rate_summary.average, $rate_summary.count, $rate_summary.std) } {$pwg->sprintf($rate_text, $rate_summary.average, $rate_summary.count, $rate_summary.std) }
@ -213,7 +212,7 @@ y.callService(
{if isset($rating)} {if isset($rating)}
<form action="{$rating.F_ACTION}" method="post" id="rateForm"> <form action="{$rating.F_ACTION}" method="post" id="rateForm">
<div> <div>
{if isset($rating.USER_RATE)}{'update_rate'|@translate}{else}{'new_rate'|@translate}{/if} <span id="updateRate">{if isset($rating.USER_RATE)}{'update_rate'|@translate}{else}{'new_rate'|@translate}{/if}</span>
: :
{foreach from=$rating.marks item=mark name=rate_loop} {foreach from=$rating.marks item=mark name=rate_loop}
{if !$smarty.foreach.rate_loop.first} | {/if} {if !$smarty.foreach.rate_loop.first} | {/if}
@ -224,6 +223,11 @@ y.callService(
{/if} {/if}
{/foreach} {/foreach}
<script type="text/javascript" src="{$ROOT_URL}{$themeconf.template_dir}/rating.js"></script> <script type="text/javascript" src="{$ROOT_URL}{$themeconf.template_dir}/rating.js"></script>
<script type="text/javascript">
makeNiceRatingForm( {ldelim}rootUrl: '{$ROOT_URL|@escape:"javascript"}', image_id: {$current.id},
updateRateText: "{'update_rate'|@translate|@escape:'javascript'}", updateRateElement: document.getElementById("updateRate"),
ratingSummaryText: "{'%.2f (rated %d times, standard deviation = %.2f)'|@translate|@escape:'javascript'}", ratingSummaryElement: document.getElementById("ratingSummary") {rdelim} );
</script>
</div> </div>
</form> </form>
{/if} {/if}

View file

@ -1,90 +1,100 @@
makeNiceRatingForm(); var gRatingOptions, gRatingButtons, gUserRating;
function makeNiceRatingForm() function makeNiceRatingForm(options)
{ {
var form = document.getElementById('rateForm'); gRatingOptions = options || {};
if (!form) return; //? template changed var form = document.getElementById('rateForm');
gRatingButtons = form.getElementsByTagName('input'); if (!form) return; //? template changed
gUserRating = ""; gRatingButtons = form.getElementsByTagName('input');
for (var i=0; i<gRatingButtons.length; i++) gUserRating = "";
{ for (var i=0; i<gRatingButtons.length; i++)
if ( gRatingButtons[i].type=="button" ) {
{ if ( gRatingButtons[i].type=="button" )
gUserRating = gRatingButtons[i].value; {
break; gUserRating = gRatingButtons[i].value;
} break;
} }
}
for (var i=0; i<gRatingButtons.length; i++) for (var i=0; i<gRatingButtons.length; i++)
{ {
var rateButton = gRatingButtons[i]; var rateButton = gRatingButtons[i];
rateButton.initialRateValue = rateButton.value; // save it as a property rateButton.initialRateValue = rateButton.value; // save it as a property
try { rateButton.type = "button"; } catch (e){}// avoid normal submit (use ajax); not working in IE6
rateButton.value = ""; //hide the text IE/Opera if (navigator.userAgent.indexOf('AppleWebKit/') == -1 ) rateButton.value = ""; //hide the text IE/Opera - breaks safari
with (rateButton.style) with (rateButton.style)
{ {
textIndent = "-50px"; //hide the text FF textIndent = "-50px"; //hide the text FF
marginLeft = marginRight = 0; marginLeft = marginRight = 0;
} }
if (i!=gRatingButtons.length-1 && rateButton.nextSibling.nodeType == 3 /*TEXT_NODE*/) if (i!=gRatingButtons.length-1 && rateButton.nextSibling.nodeType == 3 /*TEXT_NODE*/)
rateButton.parentNode.removeChild(rateButton.nextSibling); rateButton.parentNode.removeChild(rateButton.nextSibling);
if (i>0 && rateButton.previousSibling.nodeType == 3 /*TEXT_NODE*/) if (i>0 && rateButton.previousSibling.nodeType == 3 /*TEXT_NODE*/)
rateButton.parentNode.removeChild(rateButton.previousSibling); rateButton.parentNode.removeChild(rateButton.previousSibling);
if(window.addEventListener){ // Mozilla, Netscape, Firefox if(window.addEventListener){ // Mozilla, Netscape, Firefox
rateButton.addEventListener("click", updateRating, false ); rateButton.addEventListener("click", updateRating, false );
rateButton.addEventListener("mouseout", resetRatingStarDisplay, false ); rateButton.addEventListener("mouseout", resetRatingStarDisplay, false );
rateButton.addEventListener("mouseover", updateRatingStarDisplayEvt, false ); rateButton.addEventListener("mouseover", updateRatingStarDisplayEvt, false );
} }
else if(window.attachEvent) { // IE else if(window.attachEvent) { // IE
rateButton.attachEvent("onclick", updateRating); rateButton.attachEvent("onclick", updateRating);
rateButton.attachEvent("onmouseout", resetRatingStarDisplay); rateButton.attachEvent("onmouseout", resetRatingStarDisplay);
rateButton.attachEvent("onmouseover", updateRatingStarDisplayEvt); rateButton.attachEvent("onmouseover", updateRatingStarDisplayEvt);
} }
} }
resetRatingStarDisplay(); resetRatingStarDisplay();
} }
function resetRatingStarDisplay() function resetRatingStarDisplay()
{ {
updateRatingStarDisplay( gUserRating ); updateRatingStarDisplay( gUserRating );
} }
function updateRatingStarDisplay(userRating) function updateRatingStarDisplay(userRating)
{ {
for (i=0; i<gRatingButtons.length; i++) for (var i=0; i<gRatingButtons.length; i++)
{ gRatingButtons[i].className = (userRating!=="" && userRating>=gRatingButtons[i].initialRateValue ) ? "rateButtonStarFull" : "rateButtonStarEmpty";
var rateButton = gRatingButtons[i];
if (userRating!=="" && userRating>=rateButton.initialRateValue )
{
rateButton.className = "rateButtonStarFull";
}
else
{
rateButton.className = "rateButtonStarEmpty";
}
}
} }
function updateRatingStarDisplayEvt(e) function updateRatingStarDisplayEvt(e)
{ {
if (e.target) updateRatingStarDisplay(
updateRatingStarDisplay(e.target.initialRateValue); e.target ? e.target.initialRateValue : e.srcElement.initialRateValue);
else //IE
updateRatingStarDisplay(e.srcElement.initialRateValue);
} }
function updateRating(e) function updateRating(e)
{ {
if (e.target) var rateButton = e.target || e.srcElement;
var rateButton = e.target; if (rateButton.initialRateValue == gUserRating)
else //IE return false; //nothing to do
var rateButton = e.srcElement;
if (rateButton.initialRateValue == gUserRating) for (var i=0; i<gRatingButtons.length; i++) gRatingButtons[i].disabled=true;
return false; //nothing to do var y = new PwgWS(gRatingOptions.rootUrl);
// some ajax here one day would be nice y.callService(
rateButton.value = rateButton.initialRateValue; // put back real value "pwg.images.rate", {image_id: gRatingOptions.image_id, rate: rateButton.initialRateValue } ,
return true; {
onFailure: function(num, text) {
alert(num + " " + text);
document.location = rateButton.form.action + "&rate="+rateButton.initialRateValue;
},
onSuccess: function(result) {
gUserRating = rateButton.initialRateValue;
for (var i=0; i<gRatingButtons.length; i++) gRatingButtons[i].disabled=false;
if (gRatingOptions.updateRateElement) gRatingOptions.updateRateElement.innerHTML = gRatingOptions.updateRateText;
if (gRatingOptions.ratingSummaryElement)
{
var t = gRatingOptions.ratingSummaryText;
var args =[result.average, result.count, result.stdev], idx = 0, rexp = new RegExp( /%\.?\d*[sdf]/ );
_xxx = t.match( rexp );
while (idx<args.length) t=t.replace(rexp, args[idx++]);
gRatingOptions.ratingSummaryElement.innerHTML = t;
}
}
}
);
return false;
} }

13
ws.php
View file

@ -43,7 +43,7 @@ function ws_addDefaultMethods( $arr )
$service->addMethod('pwg.getVersion', 'ws_getVersion', null, $service->addMethod('pwg.getVersion', 'ws_getVersion', null,
'retrieves the PWG version'); 'retrieves the PWG version');
$service->addMethod('pwg.caddie.add', 'ws_caddie_add', $service->addMethod('pwg.caddie.add', 'ws_caddie_add',
array( array(
'image_id'=> array( 'flags'=>WS_PARAM_FORCE_ARRAY ), 'image_id'=> array( 'flags'=>WS_PARAM_FORCE_ARRAY ),
), ),
@ -94,13 +94,20 @@ function ws_addDefaultMethods( $arr )
array( array(
'image_id' => array(), 'image_id' => array(),
'comments_page' => array('default'=>0 ), 'comments_page' => array('default'=>0 ),
'comments_per_page' => array( 'comments_per_page' => array(
'default' => $conf['nb_comment_page'], 'default' => $conf['nb_comment_page'],
'maxValue' => 2*$conf['nb_comment_page'], 'maxValue' => 2*$conf['nb_comment_page'],
), ),
), ),
'retrieves information about the given photo' ); 'retrieves information about the given photo' );
$service->addMethod('pwg.images.rate', 'ws_images_rate',
array(
'image_id' => array(),
'rate' => array(),
),
'rate the image' );
$service->addMethod('pwg.images.search', 'ws_images_search', $service->addMethod('pwg.images.search', 'ws_images_search',
array( array(
'query'=>array(), 'query'=>array(),