Un clic de AJAX para apreciar la insignia

Cuando publica algo en línea, no hay muchas formas de determinar si a la gente le gusta lo que tiene que decir. Los comentarios, la piedra angular de los blogs, son demasiado exigentes y los usuarios a menudo prefieren no publicar uno. Si has visitado Behance, probablemente hayas notado su insignia de apreciación. , que es una buena solución para este problema exacto. Con él, las personas comparten su aprecio por el trabajo de alguien.

Hoy estamos implementando una insignia de este tipo, que puede incluir en cada página de su sitio web con un poco de magia jQuery. Así que continúa y descarga el zip desde el botón de arriba (¡PSD incluido! ) y continúa con el tutorial.

El esquema de la base de datos

El script que estamos haciendo hoy usa dos tablas. El primero tiene un registro para cada una de las páginas que tienen habilitado el botón apreciar. El segundo almacena la IP de la persona que votó junto con el ID único de la página. De esta manera, podemos determinar fácilmente si la persona ha votado previamente por la página y mostrar la versión adecuada del botón (activo o deshabilitado).

El campo hash contiene un MD5 suma de la URL de la página. De esta forma añadimos un ÚNICO índice que acelerará las selecciones ejecutamos en los registros, y nos aseguramos de que no haya registros duplicados en la tabla. El apreciado columna contiene el número de apreciaciones de las páginas.

Los appreciate_votes la tabla contiene la IP de la persona que votó (en forma de número entero) y la identificación de la página de appreciate_pages mesa. La marca de tiempo se actualiza automáticamente a la hora actual cuando se produce una inserción.

Puede crear estas dos tablas ejecutando el código de tables.sql en el SQL sección de phpMyAdmin del archivo descargable, parte de este tutorial.

Paso 1 - XHTML

Comencemos con la parte XHTML del tutorial. El marcado de la página es extremadamente simple. Para que el botón de apreciación funcione, solo necesita proporcionar un contenedor en el que se inserta el botón y un elemento opcional, que contiene el número total de clics en el botón. Puede omitir con seguridad el último, dejándolo con solo un div para codificar.

pagina.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>An AJAX Click To Appreciate Badge</title>

<link rel="stylesheet" type="text/css" href="styles.css" />
<link rel="stylesheet" type="text/css" href="appreciateMe/appreciate.css"/>
</head>

<body>

<div id="countDiv"></div>
<div id="main"></div>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<script src="appreciateMe/plugin.js" type="text/javascript"></script>
<script src="script.js" type="text/javascript"></script>

</body>
</html>

En la página anterior, puede ver que incluyo dos archivos de hojas de estilo. El primero es styles.css, que se utiliza para diseñar la página y appreciate.css , que se encuentra en el directorio de complementos y es responsable del estilo del botón de apreciación.

Antes de la etiqueta del cuerpo de cierre, puede ver que también incluyo la biblioteca jQuery del repositorio CDN de Google, el plugin.js archivo y script.js , que usa el complemento para crear el botón en la página. Solo necesitará cambiar el contenido de script.js para hacer que el script funcione en sus páginas.

Paso 2 - PHP

PHP maneja las interacciones de la base de datos y está en el backend de las solicitudes de AJAX. La mayor parte de la lógica del script se encuentra en c script.php que puedes ver a continuación. Pero primero echemos un vistazo a connect.php, que maneja la conexión a la base de datos.

apreciame/conectar.php

$db_host = 'localhost';
$db_user = 'YourUsername';
$db_pass = 'YouPassword';
$db_name = 'NameOfDB';

@$mysqli = new mysqli($db_host, $db_user, $db_pass, $db_name);

if (mysqli_connect_errno()) {
    die('<h1>Could not connect to the database</h1>');
}

$mysqli->set_charset("utf8");

Hasta ahora, siempre hemos usado el viejo mysql extensión para conexiones de base de datos bajo PHP, ya que es un poco más fácil de usar y quería mantener el código compatible con PHP 4. Sin embargo, con el reciente anuncio de que WordPress (nuestro motor de blogs favorito) dejará de admitir esa versión de PHP , decidí que es hora de cambiar también a la nueva versión:MySQLi (MySQL mejorado).

Como puede ver en el código anterior, la única diferencia importante con la forma anterior en que nos conectamos a una base de datos es que aquí creamos un MySQLi objeto en lugar de usar mysql_ funciones Además, como verá en un momento, cuando consultamos la base de datos, se devuelve un objeto de recurso MySQL, que a su vez tiene su propio conjunto de métodos. Esto puede sonar intimidante, pero quedará perfectamente claro una vez que lo veas en acción.

apreciame/script.php

/* Setting the error reporting level */
error_reporting(E_ALL ^ E_NOTICE);
include 'connect.php';

if(!$_GET['url'] || !filter_input(INPUT_GET,'url',FILTER_VALIDATE_URL)){
    exit;
}

$pageID         = 0;
$appreciated    = 0;
$jsonArray      = array();
$hash           = md5($_GET['url']);
$ip             = sprintf('%u',ip2long($_SERVER['REMOTE_ADDR']));

// $result is an object:
$result = $mysqli->query("SELECT id,appreciated FROM appreciate_pages WHERE hash='".$hash."'");

if($result)
{
    list($pageID,$appreciated) = $result->fetch_row();
    // fetch_row() is a method of result
}

// The submit parameter denotes that we need to write to the database

if($_GET['submit'])
{
    if(!$pageID)
    {
        // If the page has not been appreciated yet, insert a new
        // record to the database.

        $mysqli->query("
            INSERT INTO appreciate_pages
            SET
                hash='".$hash."',
                url='".$mysqli->real_escape_string($_GET['url'])."'"
        );

        if($mysqli->affected_rows){

            // The insert_id property contains the value of
            // the primary key. In our case this is also the pageID.

            $pageID = $mysqli->insert_id;
        }
    }

    // Write the vote to the DB, so the user can vote only once

    $mysqli->query("
        INSERT INTO appreciate_votes
        SET
            ip = ".$ip.",
            pageid = ".$pageID
    );

    if($mysqli->affected_rows){
        $mysqli->query("
            UPDATE appreciate_pages
            SET appreciated=appreciated+1 WHERE id=".$pageID
        );

        // Increment the appreciated field
    }

    $jsonArray = array('status'=>1);
}
else
{
    // Only print the stats

    $voted = 0;

    // Has the user voted?
    $res = $mysqli->query("
        SELECT 1 FROM appreciate_votes
        WHERE ip=".$ip." AND pageid=".$pageID
    );

    if($res->num_rows){
        $voted = 1;
    }

    $jsonArray = array('status'=>1,'voted'=>$voted,'appreciated'=>$appreciated);
}

// Telling the browser to interpret the response as JSON:
header('Content-type: application/json');

echo json_encode($jsonArray);

El script maneja dos tipos diferentes de solicitudes AJAX:solicitud de solo lectura (que devuelve un objeto JSON con información sobre el número de apreciaciones de la página y si el usuario actual ha hecho clic en el botón) y solicitudes de escritura (que guarda el voto del visitante en la base de datos y, si es necesario, también guarda la URL de la página y el hash).

Como puede ver en el fragmento de código anterior, una de las primeras cosas que hace el script es calcular el MD5 hash de la página. Esto se usa como clave única en la base de datos, ya que las URL tienen una longitud ilimitada, lo que es incompatible con las claves ÚNICAS de MySQL. Como un hash MD5 es único para la mayoría de los propósitos prácticos, podemos usarlo de manera segura en nuestras selecciones e inserciones, en lugar de las direcciones URL largas.

En la última línea del código, convertimos el $jsonArray matriz en un objeto JSON válido con el json_encode incorporado función de PHP y generarla con un applicatoin/json tipo de contenido.

Paso 3:jQuery

Dentro de apreciame directorio puede encontrar el archivo plugin.js. Debe incluirlo en la página en la que desea mostrar el botón Apreciar. Utiliza AJAX para solicitar datos del backend de PHP y utiliza la respuesta que recibe para crear el marcado del botón.

apreciame/plugin.js

function(){

    $.appreciateButton = function(options){

        // The options object must contain a URL and a Holder property
        // These are the URL of the Appreciate php script, and the
        // div in which the badge is inserted

        if(!'url' in options || !'holder' in options){
            return false;
        }

        var element = $(options.holder);

        // Forming the url of the current page:

        var currentURL =    window.location.protocol+'//'+
                    window.location.host+window.location.pathname;

        // Issuing a GET request. A rand parameter is passed
        // to prevent the request from being cached in IE

        $.get(options.url,{url:currentURL,rand:Math.random()},function(response){

            // Creating the appreciate button:

            var button = $('<a>',{
                href:'',className:'appreciateBadge',
                html:'Appreciate Me'
            });

            if(!response.voted){
                // If the user has not voted previously,
                // make the button active / clickable.
                button.addClass('active');
            }
            else button.addClass('inactive');

            button.click(function(){
                if(button.hasClass('active')){

                    button.removeClass('active').addClass('inactive');

                    if(options.count){
                        // Incremented the total count
                        $(options.count).html(1 + parseInt(response.appreciated));
                    }

                    // Sending a GET request with a submit parameter.
                    // This will save the appreciation to the MySQL DB.

                    $.getJSON(options.url,{url:currentURL,submit:1});
                }

                return false;
            });

            element.append(button);

            if(options.count){
                $(options.count).html(response.appreciated);
            }
        },'json');

        return element;
    }

})(jQuery);

El script básicamente crea un nuevo método en el objeto jQuery principal. Esto difiere de los complementos que solemos hacer, en que este tipo de complementos no se invocan en un conjunto de elementos (no es necesario seleccionar elementos). Simplemente puede llamar a $.appreciateButton() mientras pasa un objeto de configuración como parámetro. Esto es exactamente lo que hemos hecho en script.js agregar un botón a la página:

secuencia de comandos.js

$(document).ready(function(){

    // Creating an appreciate button.

    $.appreciateButton({
        url     : 'appreciateMe/script.php',    // URL to the PHP script.
        holder  : '#main',              // The button will be inserted here.
        count   : '#countDiv'           // Optional. Will show the total count.
    });

});

El objeto de configuración, que se pasa como parámetro, debe contener una url y un titular propiedades, mientras que cuenta es opcional. Tenga en cuenta que he especificado la ruta a script.php relativamente, ya que apreciarMe es un directorio secundario del directorio en el que se encuentra actualmente la página.

Sin embargo, si planea agregar el script a un sitio con una estructura de ruta variable, probablemente debería especificar una ruta absoluta. Agregue una barra diagonal inicial o proporcione una URL completa con http:// .

Paso 4 - CSS

Ahora que tenemos todo el marcado y el código en su lugar, es hora de pasar al estilo. Las reglas de CSS que dan estilo a la insignia de apreciación se encuentran en appreciate.css . Opcionalmente, puede copiar estas reglas en su archivo de hoja de estilo principal, si desea evitar la solicitud adicional, pero tenga en cuenta que deberá cambiar las rutas a las imágenes de fondo.

apreciarme/apreciar.css

.appreciateBadge{
    width:129px;
    height:129px;
    display:block;
    text-indent:-9999px;
    overflow:hidden;
    background:url('sprite.png') no-repeat;
    text-decoration:none;
    border:none;
}

.appreciateBadge.active{
    background-position:left top;
}

.appreciateBadge.active:hover{
    background-position:0 -129px;
}

.appreciateBadge.inactive{
    background-position:left bottom;
    cursor:default;
}

Hay tres versiones de la imagen de la insignia de agradecimiento. Uno predeterminado, uno flotante y uno inactivo. Los tres residen en el mismo archivo:sprite.png , uno debajo del otro. Con esta técnica, puede cambiar entre las versiones instantáneamente compensando la imagen de fondo del hipervínculo.

estilos.css

#main{
    margin:80px auto;
    width:130px;
}

#countDiv{
    color:#eee;
    font-size:35px;
    margin-right:120px;
    position:absolute;
    right:50%;
    top:265px;
}

Puede encontrar el resto de los estilos, que refinan la apariencia de page.html , en estilos.css . Solo dos conjuntos de estilos afectan directamente al botón de apreciación. El #principal div, que contiene el botón y lo centra en la página, y #countDiv en el que se inserta el número total de apreciaciones.

¡Con esto, nuestra insignia Haga clic para agradecer está completa!

Conclusión

Antes de poder ejecutar este script en su servidor, primero debe reemplazar las credenciales de MySQL en connect.php contigo mismo. Además, deberá ejecutar el contenido de tables.sql en la pestaña SQL de phpMyAdmin, por lo que se crean las dos tablas. Por último, dependiendo de las rutas de URL, es posible que deba cambiar la propiedad de URL de appreciateMe/script.php en el archivo JavaScript script.js.