Aquí mi codigo javascript
Código PHP:
$(document).ready(function() {
// iteramos todos los elementos dentro del divValoracion
$('.divValoracion').each(function() {
var mazmorra = this;
// creamos el objeto JSON que enviaremos a la página PHP
var datos = {
mazmorra_id : $(mazmorra).attr('id'), // este es el id que mencionamos antes
buscar: 1 // indicamos que queremos obtener la información y no guardar un voto
};
// cargamos datos del servidor utilizando un pedido HTTP POST
$.post(
'../paginas/votaciones/ratings.php', // archivo que va a recibir nuestro pedido
datos, // el objeto que creamos antes
// función que se ejecutará cuando obtengamos la respuesta
function(INFO) { // INFO son los datos que nos devuelve la página PHP
// data es un método jQuery que nos permite asociar datos a un objeto del DOM
$(mazmorra).data( 'puntaje', INFO );
// llamamos al método que carga los valores en las estrellas y la información
indicarVotos(mazmorra);
},
'json'
);
});
// cuando pasamos el mouse por encima de las estrellas
$('.estrellasValoracion').hover(
// la función hover necesita que definamos dos funciones
// una para cuando el puntero del mouse se posiciona sobre el elemento
function() {
// dependiendo el div en el que nos encontremos,
// a todos los divs anteriores y al que tiene el mouse encima, les agregamos esta clase
$(this).prevAll().andSelf().addClass('estrellaVotar');
// a los siguientes le quitamos esta clase
$(this).nextAll().removeClass('estrellaValoracion');
},
// y una para cuando el mouse deja el elemento
function() {
// a todos los divs anteriores y al que tenía el mouse encima, les quitamos esta clase
$(this).prevAll().andSelf().removeClass('estrellaVotar');
// llamamos al método que carga los valores originales de las estrellas
indicarVotos($(this).parent());
}
);
// este método es el que guarda el voto, al hacer click sobre una estrella
$('.estrellasValoracion').bind('click', function() {
// obtenemos la estrella sobre la que se hizo click
var estrella = this;
// obtenemos la mazmorra a la que pertenece la estrella
var mazmorra = $(this).parent();
// creamos el objeto para enviar a la página PHP
var datosClick = {
clickEstrella : $(estrella).attr('class'),
mazmorra_id : $(estrella).parent().attr('id')
};
// cargamos datos del servidor utilizando un pedido HTTP POST
$.post(
'../paginas/votaciones/ratings.php', // archivo que recibe nuestro pedido
datosClick, // datos que le enviamos a la página
// función que se ejecuta cuando obtenemos la respuesta
function(INFO) { // INFO son los datos que nos devolvió la página PHP
// data nos permite asociar datos a un objeto del DOM
mazmorra.data( 'puntaje', INFO );
// llamaos al método que llena los valores
indicarVotos(mazmorra);
},
'json'
);
});
});
// función encargada de tomar los datos que se obtuvieron de la página PHP
// y cargar las estrellas correspondientes
function indicarVotos(mazmorra) {
// extraemos la información guardada el objeto DOM donde está la mazmorra
// y creamos 3 variables para mostrar los datos
var promedioRedondeado = $(mazmorra).data('puntaje').promedioRedondeado;
var votos = $(mazmorra).data('puntaje').numeroDeVotos;
var promedioExacto = $(mazmorra).data('puntaje').promedioExacto;
// buscamos la estrella de la mazmorra que tenga el número igual al promedio redondeado
// de esa para atrás, les cargamos la clase estrellaValoración
$(mazmorra).find('.estrella_' + promedioRedondeado).prevAll().andSelf().addClass('estrellaValoracion');
// a las que la suceden (si las hubiera) le quitamos la clase (por si la tenían) para que queden vacías
$(mazmorra).find('.estrella_' + promedioRedondeado).nextAll().removeClass('estrellaValoracion');
// mostramos la cantidad de votos y el promedio exacto
$(mazmorra).find('.votosTotales').text( votos + ' votos (' + promedioExacto + ')' );
}
y aquí ratings.php
Código PHP:
<?php
include "../../conexion.php";
// se crea un nuevo objeto y le pasamos el id de la mazmorra que vino por el postback
$rating = new ratings($_POST['mazmorra_id']);
// si en el postback se indicó la variable buscar, obtenemos los ratings, sino guardamos el voto
isset($_POST['buscar']) ? $rating->obtenerRating() : $rating->votar();
// definición de la clase
class ratings {
// el archivo donde guardamos los datos
var $data_file = './ratings.data.txt';
private $mazmorra_id;
private $data = array();
// el constructor de la clase va a recibir la mazmorra
function __construct($mazmo) {
// guardamos la mazmorra en la propiedad
$this->mazmorra_id = $mazmo;
// file_get_contents devuelve lo que está en el archivo de texto a una variable string
$info = file_get_contents($this->data_file);
// si se cargó el archivo
if($info) {
// transformamos los datos planos a un array en php
$this->data = unserialize($info);
}
}
public function obtenerRating() {
// si en el arreglo con los datos del archivo txt (que se cargó en el constructor), está el id de la mazmorra
if($this->data[$this->mazmorra_id]) {
// devolvemos los datos de la mazmorra por JSON a la pagína
echo json_encode($this->data[$this->mazmorra_id]);
}
else { // caso contrario
// cargamos los datos de la mazmorra al arreglo, con los valores por defecto
$data['mazmorra_id'] = $this->mazmorra_id;
$data['numeroDeVotos'] = 0;
$data['votosTotales'] = 0;
$data['promedioExacto'] = 0;
$data['promedioRedondeado'] = 0;
// devolvemos el objeto recién creado por JSON a la página
echo json_encode($data);
}
}
public function votar() {
session_start();
$link1 = mysqli_connect(SERVER, USER, PASS);
mysqli_select_db($link1, BD);
$query1 = "INSERT INTO votaciones VALUES(NULL,'".$_SESSION['idusuario']."','".$_POST['mazmorra_id']."')";
$result1 = mysqli_query($link1, $query1);
// necesitamos saber qué estrella es la que se votó
// para eso, usamos preg_match, que realiza una comparación
// tomando la expresión regular, la cadena de entrada (la estrella en la que hizo click) y dejando el resultado en $resultado
preg_match('/estrella_([1-5]{1})/', $_POST['clickEstrella'], $resultado);
// guardamos el valor de la estrella
$votar = $resultado[1];
$ID = $this->mazmorra_id;
// si existe la mazmorra en el arreglo (cargado en el constructor)
if($this->data[$ID]) {
// aumentamos el número de votos en 1
$this->data[$ID]['numeroDeVotos'] += 1;
// sumamos el voto a los votos totales
$this->data[$ID]['votosTotales'] += $votar;
}
else { // si no existe la mazmorra
// indicamos que es el primer voto
$this->data[$ID]['numeroDeVotos'] = 1;
// indicamos el número del primer voto
$this->data[$ID]['votosTotales'] = $votar;
}
// calculamos el promedioExacto
$this->data[$ID]['promedioExacto'] =
round( $this->data[$ID]['votosTotales'] / $this->data[$ID]['numeroDeVotos'], 1 );
// redondeamos el promedio, para no tener que volver a hacerlo en la página
$this->data[$ID]['promedioRedondeado'] = round( $this->data[$ID]['promedioExacto'] );
// guardamos el arreglo en formato plano de nuevo en el archivo de texto
file_put_contents($this->data_file, serialize($this->data));
// obtenemos el nuevo rating para enviárselo a la página
$this->obtenerRating();
}
}
?>
Por último los cambios recientes que he realizado para intentar solucionarlo.
Es sólo un ejemplo de lo que hice, en realidad lo aplicaba a todo. Pero igualmente no me funcionaba.
Código PHP:
<script>
function myFunction<?php echo $idmazmorra_ ?>() {
document.getElementById("estrella1<?php echo $idmazmorra_ ?>").className = "estrella_1 estrellaSinValoracion";
}
</script>
<?php
echo "<div id='$idmazmorra_' class='divValoracion'>";
?>
<div id="estrella1<?php echo $idmazmorra_ ?>" class="estrella_1 estrellasValoracion" onclick="myFunction<?php echo $idmazmorra_ ?>()"></div>
<div class="votosTotales" onclick="myFunction<?php echo $idmazmorra_ ?>()">Necesita más votos</div>
<?php
echo '</div>';
?>
donde $idmazmorra_ es la id de la mazmorra que la he guardado en esa variable.