- 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
parent df29ffbde7
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 !in_array($rate, $conf['rate_items']))
{
return;
return false;
}
$user_anonymous = is_autorize_status(ACCESS_CLASSIC) ? false : true;
if ($user_anonymous and !$conf['rate_anonymous'])
{
return;
return false;
}
$ip_components = explode('.', $_SERVER["REMOTE_ADDR"]);
@ -118,17 +118,20 @@ INSERT
// update of images.average_rate field
$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.'
WHERE element_id = '.$image_id.'
;';
$row = mysql_fetch_array(pwg_query($query));
$row = mysql_fetch_assoc(pwg_query($query));
$query = '
UPDATE '.IMAGES_TABLE.'
SET average_rate = '.$row['average_rate'].'
SET average_rate = '.$row['average'].'
WHERE id = '.$image_id.'
;';
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') );
}
/**
* 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
*/

View file

@ -162,7 +162,6 @@ y.callService(
{
selectElement.disabled = true;
var y = new PwgWS(rootUrl);
y.callService(
"pwg.images.setPrivacyLevel", {image_id: id, level:level} ,
{
@ -182,7 +181,7 @@ y.callService(
{if isset($rate_summary) }
<tr>
<td class="label">{'Average rate'|@translate}</td>
<td class="value">
<td class="value" id="ratingSummary">
{if $rate_summary.count}
{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) }
@ -213,7 +212,7 @@ y.callService(
{if isset($rating)}
<form action="{$rating.F_ACTION}" method="post" id="rateForm">
<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}
{if !$smarty.foreach.rate_loop.first} | {/if}
@ -224,6 +223,11 @@ y.callService(
{/if}
{/foreach}
<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>
</form>
{/if}

View file

@ -1,90 +1,100 @@
makeNiceRatingForm();
var gRatingOptions, gRatingButtons, gUserRating;
function makeNiceRatingForm()
function makeNiceRatingForm(options)
{
var form = document.getElementById('rateForm');
if (!form) return; //? template changed
gRatingButtons = form.getElementsByTagName('input');
gRatingOptions = options || {};
var form = document.getElementById('rateForm');
if (!form) return; //? template changed
gUserRating = "";
for (var i=0; i<gRatingButtons.length; i++)
{
if ( gRatingButtons[i].type=="button" )
{
gUserRating = gRatingButtons[i].value;
break;
}
}
gRatingButtons = form.getElementsByTagName('input');
gUserRating = "";
for (var i=0; i<gRatingButtons.length; i++)
{
if ( gRatingButtons[i].type=="button" )
{
gUserRating = gRatingButtons[i].value;
break;
}
}
for (var i=0; i<gRatingButtons.length; i++)
{
var rateButton = gRatingButtons[i];
rateButton.initialRateValue = rateButton.value; // save it as a property
for (var i=0; i<gRatingButtons.length; i++)
{
var rateButton = gRatingButtons[i];
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
with (rateButton.style)
{
textIndent = "-50px"; //hide the text FF
marginLeft = marginRight = 0;
}
if (navigator.userAgent.indexOf('AppleWebKit/') == -1 ) rateButton.value = ""; //hide the text IE/Opera - breaks safari
with (rateButton.style)
{
textIndent = "-50px"; //hide the text FF
marginLeft = marginRight = 0;
}
if (i!=gRatingButtons.length-1 && rateButton.nextSibling.nodeType == 3 /*TEXT_NODE*/)
rateButton.parentNode.removeChild(rateButton.nextSibling);
if (i>0 && rateButton.previousSibling.nodeType == 3 /*TEXT_NODE*/)
rateButton.parentNode.removeChild(rateButton.previousSibling);
if (i!=gRatingButtons.length-1 && rateButton.nextSibling.nodeType == 3 /*TEXT_NODE*/)
rateButton.parentNode.removeChild(rateButton.nextSibling);
if (i>0 && rateButton.previousSibling.nodeType == 3 /*TEXT_NODE*/)
rateButton.parentNode.removeChild(rateButton.previousSibling);
if(window.addEventListener){ // Mozilla, Netscape, Firefox
rateButton.addEventListener("click", updateRating, false );
rateButton.addEventListener("mouseout", resetRatingStarDisplay, false );
rateButton.addEventListener("mouseover", updateRatingStarDisplayEvt, false );
}
else if(window.attachEvent) { // IE
rateButton.attachEvent("onclick", updateRating);
rateButton.attachEvent("onmouseout", resetRatingStarDisplay);
rateButton.attachEvent("onmouseover", updateRatingStarDisplayEvt);
}
}
resetRatingStarDisplay();
if(window.addEventListener){ // Mozilla, Netscape, Firefox
rateButton.addEventListener("click", updateRating, false );
rateButton.addEventListener("mouseout", resetRatingStarDisplay, false );
rateButton.addEventListener("mouseover", updateRatingStarDisplayEvt, false );
}
else if(window.attachEvent) { // IE
rateButton.attachEvent("onclick", updateRating);
rateButton.attachEvent("onmouseout", resetRatingStarDisplay);
rateButton.attachEvent("onmouseover", updateRatingStarDisplayEvt);
}
}
resetRatingStarDisplay();
}
function resetRatingStarDisplay()
{
updateRatingStarDisplay( gUserRating );
updateRatingStarDisplay( gUserRating );
}
function updateRatingStarDisplay(userRating)
{
for (i=0; i<gRatingButtons.length; i++)
{
var rateButton = gRatingButtons[i];
if (userRating!=="" && userRating>=rateButton.initialRateValue )
{
rateButton.className = "rateButtonStarFull";
}
else
{
rateButton.className = "rateButtonStarEmpty";
}
}
for (var i=0; i<gRatingButtons.length; i++)
gRatingButtons[i].className = (userRating!=="" && userRating>=gRatingButtons[i].initialRateValue ) ? "rateButtonStarFull" : "rateButtonStarEmpty";
}
function updateRatingStarDisplayEvt(e)
{
if (e.target)
updateRatingStarDisplay(e.target.initialRateValue);
else //IE
updateRatingStarDisplay(e.srcElement.initialRateValue);
updateRatingStarDisplay(
e.target ? e.target.initialRateValue : e.srcElement.initialRateValue);
}
function updateRating(e)
{
if (e.target)
var rateButton = e.target;
else //IE
var rateButton = e.srcElement;
if (rateButton.initialRateValue == gUserRating)
return false; //nothing to do
// some ajax here one day would be nice
rateButton.value = rateButton.initialRateValue; // put back real value
return true;
var rateButton = e.target || e.srcElement;
if (rateButton.initialRateValue == gUserRating)
return false; //nothing to do
for (var i=0; i<gRatingButtons.length; i++) gRatingButtons[i].disabled=true;
var y = new PwgWS(gRatingOptions.rootUrl);
y.callService(
"pwg.images.rate", {image_id: gRatingOptions.image_id, rate: rateButton.initialRateValue } ,
{
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,
'retrieves the PWG version');
$service->addMethod('pwg.caddie.add', 'ws_caddie_add',
$service->addMethod('pwg.caddie.add', 'ws_caddie_add',
array(
'image_id'=> array( 'flags'=>WS_PARAM_FORCE_ARRAY ),
),
@ -94,13 +94,20 @@ function ws_addDefaultMethods( $arr )
array(
'image_id' => array(),
'comments_page' => array('default'=>0 ),
'comments_per_page' => array(
'default' => $conf['nb_comment_page'],
'comments_per_page' => array(
'default' => $conf['nb_comment_page'],
'maxValue' => 2*$conf['nb_comment_page'],
),
),
'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',
array(
'query'=>array(),