Advertisement
  1. Web Design
  2. HTML/CSS
  3. HTML

Créer un système de mise à jour sous licence: l'API du gestionnaire de licences

Scroll to top
Read Time: 37 min
This post is part of a series called Create a License Controlled Theme and Plugin Update System.
Create a License Controlled Update System: The License Manager Plugin
Create a License Controlled Update System: Doing the Update

() translation by (you can also view the original English article)

Il s’agit du deuxième tutoriel d’une série de trois didacticiels sur la construction d’un plug-in WordPress contrôlé par licence et d’un système de mise à jour des thèmes.

Dans la première partie de la série, nous avons créé un plugin WordPress pour stocker et gérer les licences logicielles. Dans la troisième partie, nous allons faire un thème WordPress et le plugin utilisera ce serveur de gestionnaire de licences pour vérifier les mises à jour et les télécharger.

Dans ce didacticiel, nous allons construire l'interface entre les deux: une API avec deux actions pouvant être appelées depuis un site externe pour obtenir des informations sur un produit et sa licence et pour télécharger le produit.

En travaillant sur le plugin, vous apprendrez les sujets suivants:

  • Construire une API sur un plugin WordPress.
  • Création d'une page de paramètres.
  • Téléchargement de fichiers vers Amazon Simple Storage Service (S3)
  • Utilisation du kit AWS SDK pour créer des URL signées pouvant être utilisées pour télécharger des fichiers privés à partir de S3.

Nous allons continuer à créer le plug-in en plus du code que nous avons créé dans la première partie du didacticiel. Vous devriez donc pouvoir créer un plug-in fonctionnel en suivant les étapes. Si vous souhaitez suivre le didacticiel à l'aide du code prêt à l'emploi, consultez le code source dans le référentiel Tuts + Github lié à droite.

Commençons.

Création de l'API License Manager

Une API peut signifier beaucoup de choses différentes. Dans ce tutoriel, cela signifie un ensemble d'actions (souvent appelées méthodes) pouvant être appelées via une connexion HTTP pour accéder à une partie bien définie et limitée des fonctionnalités de l'application.

Dans la troisième partie de la série, nous allons utiliser cette API dans un plugin ou un thème WordPress premium pour vérifier la validité de la licence et pour télécharger les mises à jour, mais l'API elle-même ne définit aucune limitation à cet égard. L’application utilisant l’API pourrait tout aussi bien être un jeu qui doit être activé avec une clé de licence avant de pouvoir y jouer.

Notre API sera accessible via l'URL https://<yoursite>/api/license-manager/v1/, où votre site est l'URL de votre site WordPress exécutant le plugin WP License Manager. L'API aura deux fonctions:

  • info: retourne des informations sur le produit demandé si la clé de licence donnée est valide.
  • get: Retourne le fichier téléchargeable si la clé de licence donnée est valide.

Construisons-le!

Étape 1: Créer une classe pour la fonctionnalité de l'API

Jusqu'ici, nous avons bien utilisé les classes existantes du plugin WordPress Plugin Boilerplate, mais maintenant, pour que les choses restent claires, ajoutons une nouvelle classe pour stocker les fonctionnalités spécifiques à l'API.

Une API est une partie publique du plug-in, de sorte que la nouvelle classe doit accéder au répertoire public du plugin boilerplate. Appelez la classe d'API Wp_License_Manager_API et placez-la dans un fichier appelé class-wp-license-manager-api.php.

Faites-en une classe vide pour l'instant:

1
/**

2
 * The API handler for handling API requests from themes and plugins using

3
 * the license manager.

4
 *

5
 * @package    Wp_License_Manager

6
 * @subpackage Wp_License_Manager/public

7
 * @author     Jarkko Laine <jarkko@jarkkolaine.com>

8
 */
9
class Wp_License_Manager_API {
10
11
}

Liez la classe nouvellement créée à votre classe Wp_License_Manager_Public pour la rendre disponible en cas de besoin. Tout d'abord, ajoutez un champ pour la classe d'API:

1
/**

2
 * @var     License_Manager_API     The API handler

3
 */
4
private $api;

Ensuite, initialisez-le dans le constructeur (la ligne 11 est la nouvelle, tout le reste existe déjà dans la première partie):

1
/**
2
 * Initialize the class and set its properties.
3
 *
4
 * @var      string    $plugin_name       The name of the plugin.
5
 * @var      string    $version    The version of this plugin.
6
 */
7
public function __construct( $plugin_name, $version ) {
8
    $this->plugin_name = $plugin_name;
9
    $this->version = $version;
10
11
    $this->api = new Wp_License_Manager_API();  
12
}

Nous sommes maintenant prêts à créer la fonctionnalité de l'API.

Étape 2: Définir les variables de requête pour l'API

Comme je l'ai mentionné ci-dessus, nous allons commencer par créer un format d'URL spécial pour accéder à l'API. De cette façon, nous pouvons séparer les appels d'API pour les autres demandes adressées au site sans vous embrouiller avec le reste du contenu du site WordPress.

Par défaut (et sous le capot), les URL WordPress associent index.php et un ensemble de paramètres de requête, par exemple: http://<yoursite>/?p=123 (index.php est omis dans l’URL, mais c’est là que va la demande). La plupart des sites utilisent des paramètres de permalien plus agréables - et nous le ferons également - pour rendre les URL plus lisibles, mais ce n'est qu'une couche de décoration au-dessus de cette fonctionnalité essentielle.

Donc, pour créer notre API, la première chose à faire est d'ajouter une variable de requête personnalisée, __wp_license_api, à utiliser à la place de p. Ensuite, une fois que cela fonctionnera, nous ajouterons des paramètres de permalien personnalisés pour rendre l'API plus lisible.

À la fin de la fonction define_public_hooks de la classe Wp_License_Manager, ajoutez les lignes suivantes pour lier un filtre au hook query_vars:

1
// The external API setup

2
$this->loader->add_filter( 'query_vars', $plugin_public, 'add_api_query_vars' );

Ajoutez ensuite la fonction dans la classe Wp_License_Manager_Public:

1
/**

2
 * Defines the query variables used by the API.

3
 *

4
 * @param $vars     array   Existing query variables from WordPress.

5
 * @return array    The $vars array appended with our new variables

6
 */
7
public function add_api_query_vars( $vars ) {
8
    // The parameter used for checking the action used

9
    $vars []= '__wp_license_api';
10
11
    // Additional parameters defined by the API requests

12
    $api_vars = $this->api->get_api_vars();
13
14
    return array_merge( $vars, $api_vars );
15
}

Cette fonction ajoute nos variables de requête à la liste blanche de WordPress en les ajoutant au tableau $vars transmis par le filtre et en renvoyant le tableau ajouté:

Ligne 9: Ajoutez la variable permettant de spécifier l'action de l'API (et reconnaissant que la demande est réellement destinée à l'API), __wp_license_api.

Ligne 12: Donnez à la classe d'API l'occasion d'ajouter tout paramètre supplémentaire utilisé par ses fonctions.

Ligne 14: Retournez le tableau $vars mis à jour.

Pour que le code fonctionne, nous devons toujours créer la fonction get_api_vars:

1
/**

2
 * Returns a list of variables used by the API

3
 *

4
 * @return  array    An array of query variable names.

5
 */
6
public function get_api_vars() {
7
    return array( 'l',  'e', 'p' );
8
}

Pour l'instant, comme l'API est encore très simple, j'ai décidé de simplifier cette fonction et d'inclure simplement tous les paramètres dans un tableau et de les renvoyer.

Étape 3: attraper les demandes d'API

Nous avons maintenant la liste blanche de nos variables de requête, mais elles ne font encore rien. Pour que les variables fassent la différence, nous devons créer une fonctionnalité permettant de capturer les demandes d'API.

Cela peut être fait en utilisant l'action WordPress parse_request.

Dans define_public_hooks de Wp_License_Manager, liez une fonction à l'action:

1
$this->loader->add_action( 'parse_request', $plugin_public, 'sniff_api_requests' );

Désormais, toutes les futures demandes adressées à cette installation WordPress passeront par cette fonction avant d’être transmises aux propres fonctions de traitement des demandes de WordPress. Cela signifie que nous devons garder la fonction de gestionnaire légère: Vérifiez si __wp_license_api a été défini et si ce n'est pas le cas, revenez rapidement et laissez WordPress continuer. Si oui, il est acceptable de procéder à des manipulations plus complexes. C’est notre demande et nous y répondrons

La fonction sniff_api_requests se rend dans Wp_License_Manager_Public:

1
/**

2
 * A sniffer function that looks for API calls and passes them to our API handler.

3
 */
4
public function sniff_api_requests() {
5
    global $wp;
6
    if ( isset( $wp->query_vars['__wp_license_api'] ) ) {
7
        $action = $wp->query_vars['__wp_license_api'];
8
        $this->api->handle_request( $action, $wp->query_vars );
9
10
        exit;
11
    }
12
}

Ligne 6: Vérifiez si la variable de requête d'action API est présente. Si oui, il s'agit d'un appel que cette API doit gérer.

Lignes 7 à 8: transmettez la demande à la fonction handle_request de la classe d'API à traiter. Nous allons créer cette fonction ensuite.

Ligne 10: Arrêtez l'exécution de la requête WordPress une fois l'appel API traité. Celui-ci est important car sinon, l'exécution continuerait sous WordPress et générerait une page d'erreur 404 après la sortie de l'API.

Ensuite, ajoutons la fonction handle_request.

Pour le moment, c'est une implémentation de base que nous pouvons utiliser pour vérifier que notre framework fonctionne. J'ai inclus des espaces réservés pour les deux actions que nous allons créer dans ce didacticiel et une réponse par défaut à envoyer si un utilisateur utilise une action de l'API que nous ne prenons pas en charge.

1
/**

2
 * The handler function that receives the API calls and passes them on to the

3
 * proper handlers.

4
 *

5
 * @param $action   string  The name of the action

6
 * @param $params   array   Request parameters

7
 */
8
public function handle_request( $action, $params ) {
9
    switch ( $action ) {
10
        case 'info':
11
            break;
12
13
        case 'get':
14
            break;
15
16
        default:
17
            $response = $this->error_response( 'No such API action' );
18
            break;
19
    }
20
21
    $this->send_response( $response );
22
}

Ligne 17: $response est un tableau contenant les informations à transmettre à l'application appelant l'API.

Ligne 21: Imprimez la réponse sous forme de chaîne codée JSON.

Pour que la fonction fonctionne, nous avons toujours besoin d'ajouter les fonctions d'assistance utilisées: send_response et error_response.

Tout d'abord, send_response:

1
/**

2
 * Prints out the JSON response for an API call.

3
 *

4
 * @param $response array   The response as associative array.

5
 */
6
private function send_response( $response ) {
7
    echo json_encode( $response );
8
}

Puis error_response. Cette fonction crée un tableau avec le message d'erreur donné. En utilisant une fonction pour générer le tableau, nous pouvons nous assurer que tous les messages d'erreur sont formatés de la même manière et facilement changer le formatage si nécessaire ultérieurement dans le cycle de vie du plugin.

Pour le moment, j'ai décidé de choisir une version de base ne contenant qu'un message d'erreur à l'intérieur du tableau:

1
/**

2
 * Generates and returns a simple error response. Used to make sure every error

3
 * message uses same formatting.

4
 *

5
 * @param $msg      string  The message to be included in the error response.

6
 * @return array    The error response as an array that can be passed to send_response.

7
 */
8
private function error_response( $msg ) {
9
    return array( 'error' => $msg );
10
}

Vous avez maintenant construit la structure dans laquelle nous pouvons commencer à créer les actions de l'API. Pour le tester, essayez d'appeler une action d'API non existante, par exemple http://<yoursite>/?__ wp_license_api=dummy-action, dans une fenêtre de navigateur.

Vous devriez voir quelque chose comme ça:

Même si l'API renvoie toujours juste un message d'erreur, le test montre que la demande est dirigée vers la fonction de gestionnaire appropriée et n'est pas mélangée au reste du flux WordPress. Comme nous le voulions.

Maintenant, avant de commencer à ajouter des fonctionnalités API, facilitons la mémorisation de l'URL de l'API.

Étape 4: Créer un format d'URL personnalisé pour l'API

Bien que http://<yoursite>/?__wp_license_api=<action> fonctionne, ce n'est pas très joli et cela expose également un peu trop des éléments internes de l'implémentation de l'API à mon avis. Créons donc un format d’URL plus agréable à utiliser à sa place.

Pour rappel, au début de cette section, voici l’URL que nous utiliserons: http://<yoursite>/api/license-manager/v1/

J'ai ajouté v1 à l'URL de l'API pour le cas où nous pourrions nous retrouver à supporter plusieurs versions différentes de l'API. Avoir les informations de version dès le début facilite l'ajout ultérieur de nouvelles versions.

Tout d’abord, pour créer de "jolies" URL comme celles-ci, définissez l’option Permaliens dans les paramètres WordPress sur une valeur autre que la valeur par défaut (toutes les autres options, à l’exception de "Par défaut", vont bien).

Ensuite, ajoutons un filtre pour créer une nouvelle règle de réécriture. Ajoutez l'enregistrement du filtre aux define_public_hooks de Wp_License_Manager:

1
$this->loader->add_action( 'init', $plugin_public, 'add_api_endpoint_rules' );

Ensuite, créez la fonction (dans Wp_License_Manager_Public):

1
/**

2
 * The permalink structure definition for API calls.

3
 */
4
public function add_api_endpoint_rules() {
5
    add_rewrite_rule( 'api/license-manager/v1/(info|get)/?',
6
        'index.php?__wp_license_api=$matches[1]', 'top' );
7
8
    // If this was the first time, flush rules

9
    if ( get_option( 'wp-license-manager-rewrite-rules-version' ) != '1.1' ) {
10
        flush_rewrite_rules();
11
        update_option( 'wp-license-manager-rewrite-rules-version', '1.1' );
12
    }
13
}

Ligne 5: À l'aide d'une expression régulière, définissez une nouvelle règle de réécriture d'URL pour envoyer les demandes au format conforme à ce que nous avions en tête pour l'URL utilisée à l'étape précédente. (info|get) définit les méthodes de l'API que l'API doit accepter.

Lignes 9-12: Enregistrez les règles de réécriture pour les rendre actives. flush_rewrite_rules est un appel consommateur de ressources. J'ai donc ajouté une vérification autour de lui pour m'assurer que le vidage n'est effectué que lorsque les règles ont été modifiées.

Maintenant que cette étape est terminée, toute demande adressée à http://<yoursite>/api/license-manager/v1<action>est convertie en une demande destinée à http://<yoursite>/?__wp_license_api=<action> . Testez cela avec la même action fictive de l'étape précédente - vous devriez maintenant obtenir le même résultat en utilisant les deux URL.

La structure de l'API est maintenant en place et nous pouvons commencer à y ajouter des fonctionnalités.

Étape 5: Créer la fonctionnalité de vérification des licences

Les deux actions de l'API que nous allons construire dans ce tutoriel commencent par vérifier la licence de l'utilisateur.

Au début, j’écrivais le code de vérification de licence séparément pour chacun d’eux, mais j’ai vite remarqué qu’ils étaient exactement les mêmes. Pour moi, c'est un bon signe qu'il est temps de refactoriser.

Pour gagner du temps, sautons l'étape où nous écrivons deux fois le même code et passons directement à la version finale et mettons le code commun dans une fonction qui lui est propre.

Dans Wp_License_Manager_API, créez une fonction appelée verify_license_and_execute. Cette fonction servira d'étape supplémentaire entre la fonction que nous avons créée précédemment et le traitement réel des demandes.

1
/**

2
 * Checks the parameters and verifies the license, then forwards the request to the

3
 * actual API request handlers.

4
 *

5
 * @param $action_function  callable    The function (or array with class and function) to call

6
 * @param $params           array       The WordPress request parameters.

7
 * @return array            API response.

8
 */
9
private function verify_license_and_execute( $action_function, $params ) {
10
    if ( ! isset( $params['p'] ) || ! isset( $params['e'] ) || ! isset( $params['l'] ) ) {
11
        return $this->error_response( 'Invalid request' );
12
    }
13
14
    $product_id = $params['p'];
15
    $email = $params['e'];
16
    $license_key = $params['l'];
17
18
    // Find product

19
    $posts = get_posts(
20
        array (
21
            'name' => $product_id,
22
            'post_type' => 'wplm_product',
23
            'post_status' => 'publish',
24
            'numberposts' => 1
25
        )
26
    );
27
28
    if ( ! isset( $posts[0] ) ) {
29
        return $this->error_response( 'Product not found.' );
30
    }
31
32
    // Verify license

33
    if ( ! $this->verify_license( $posts[0]->ID, $email, $license_key ) ) {
34
        return $this->error_response( 'Invalid license or license expired.' );
35
    }
36
37
    // Call the handler function

38
    return call_user_func_array( $action_function, array( $posts[0], $product_id, $email, $license_key ) );
39
}

Lignes 10-12: Vérifiez que tous les paramètres liés à la licence sont présents. p est le slug du produit, e est l'adresse de messagerie de l'utilisateur et l est la clé de licence.

Lignes 14-16: Collectez et désinfectez les paramètres.

Lignes 19-26: Recherchez la publication correspondant à l'ID de produit donné. Comme je l'ai mentionné ci-dessus, l'ID du produit est en fait le slug post-produit du produit, afin de permettre à l'utilisateur de connaître plus facilement la valeur appropriée.

Lignes 28-30: Si le produit n'est pas trouvé, renvoyer une erreur.

Lignes 33-35: Effectuez la validation de la clé de licence réelle. Nous allons créer cette fonction ensuite.

Ligne 38: Appelez la fonction responsable du traitement de l'action de l'API. En tant qu’idée de développement pour l’avenir, ce serait un excellent endroit pour un filtre que d’autres plugins pourraient utiliser pour remplacer la fonction de gestionnaire si nécessaire ...

Ensuite, ajoutons la fonction de vérification de la licence:

1
/**

2
 * Checks whether a license with the given parameters exists and is still valid.

3
 *

4
 * @param $product_id   int     The numeric ID of the product.

5
 * @param $email        string  The email address attached to the license.

6
 * @param $license_key  string  The license key.

7
 * @return bool                 true if license is valid. Otherwise false.

8
 */
9
private function verify_license( $product_id, $email, $license_key ) {
10
    $license = $this->find_license( $product_id, $email, $license_key );
11
    if ( ! $license ) {
12
        return false;
13
    }
14
15
    $valid_until = strtotime( $license['valid_until'] );
16
    if ( $license['valid_until'] != '0000-00-00 00:00:00' && time() > $valid_until ) {
17
        return false;
18
    }
19
20
    return true;
21
}

Lignes 10-13: Recherchez la licence dans la base de données (nous ajouterons cette fonction ensuite) en utilisant les paramètres envoyés. Si la licence n'est pas trouvée, elle ne peut pas être valide, nous pouvons donc renvoyer false.

Lignes 15-18: Si la licence existe, vérifiez si elle a expiré. Dans la première partie du didacticiel, nous avons défini que 0000-00-00 00:00:00 est utilisé pour une licence qui n'expire jamais.

Ligne 20: Tous les chèques sont passés, la licence est valide.

Enfin, pour compléter le code de validation de la licence, nous avons besoin de la fonction permettant de récupérer une licence de la base de données.

Ajoutez la fonction, find_license:

1
/**

2
 * Looks up a license that matches the given parameters.

3
 *

4
 * @param $product_id   int     The numeric ID of the product.

5
 * @param $email        string  The email address attached to the license.

6
 * @param $license_key  string  The license key

7
 * @return mixed                The license data if found. Otherwise false.

8
 */
9
private function find_license( $product_id, $email, $license_key ) {
10
    global $wpdb;
11
    $table_name = $wpdb->prefix . 'product_licenses';
12
13
    $licenses = $wpdb->get_results(
14
        $wpdb->prepare( "SELECT * FROM $table_name WHERE product_id = %d AND email = '%s' AND license_key = '%s'",
15
            $product_id, $email, $license_key ), ARRAY_A );
16
17
    if ( count( $licenses ) > 0 ) {
18
        return $licenses[0];
19
    }
20
21
    return false;
22
}

Dans cette fonction, nous effectuons une requête SQL pour rechercher une licence avec les paramètres exacts envoyés, l'id du produit, l'adresse de messagerie et la clé de licence. De cette façon, nous n'avons pas besoin d'analyser la réponse en plus de voir s'il y a un résultat ou non.

Si une licence est trouvée, la fonction la renvoie. Sinon, il retourne false.

Étape 6: ajoutez l'action API d'informations sur le produit

Ensuite, ajoutons la première des deux actions, info. Dans la fonction handle_request que nous avons créée il y a quelque temps, indiquez la branche de cas pour l'action:

1
case 'info':
2
    $response = $this->verify_license_and_execute( array( $this, 'product_info' ), $params );
3
    break;

La ligne que nous avons ajoutée appelle notre fonction verify_license_and_execute avec deux paramètres:

  • Le premier paramètre devrait vous être familier avec les actions et les filtres WordPress que nous avons créés tout au long de la série de tutoriels. Il passe le nom de la fonction que nous voulons utiliser pour gérer l'action une fois la licence vérifiée. Comme la fonction est à l'intérieur d'une classe, nous devons passer un tableau au lieu du nom de la fonction.
  • Le second paramètre est la liste de tous les paramètres de requête envoyés à WordPress.

Nous avons déjà examiné ce qui se passe dans verify_license_and_execute, ajoutons maintenant la fonction product_info. Cette fonction va collecter des informations sur le produit et les renvoyer sous forme de tableau.

Comme vous vous en souvenez sans doute de la première partie du didacticiel, les produits sont stockés dans le plug-in du gestionnaire de licences sous la forme d'un type d'article personnalisé avec une méta-boîte permettant de saisir des informations supplémentaires sur le produit. Dans cette fonction, nous allons puiser dans ces données et remplir le tableau $response avec des informations sur le produit demandé:

1
/**
2
 * The handler for the "info" request. Checks the user's license information and
3
 * returns information about the product (latest version, name, update url).
4
 *
5
 * @param   $product        WP_Post   The product object
6
 * @param   $product_id     string    The product id (slug)
7
 * @param   $email          string    The email address associated with the license
8
 * @param   $license_key    string  The license key associated with the license
9
 *
10
 * @return  array           The API response as an array.
11
 */
12
private function product_info( $product, $product_id, $email, $license_key ) {
13
    // Collect all the metadata we have and return it to the caller
14
    $meta = get_post_meta( $product->ID, 'wp_license_manager_product_meta', true );
15
16
    $version = isset( $meta['version'] ) ? $meta['version'] : '';        
17
    $tested = isset( $meta['tested'] ) ? $meta['tested'] : '';
18
    $last_updated = isset( $meta['updated'] ) ? $meta['updated'] : '';
19
    $author = isset( $meta['author'] ) ? $meta['author'] : '';
20
    $banner_low = isset( $meta['banner_low'] ) ? $meta['banner_low'] : '';
21
    $banner_high = isset( $meta['banner_high'] ) ? $meta['banner_high'] : '';
22
23
    return array(
24
        'name' => $product->post_title,
25
        'description' => $product->post_content,
26
        'version' => $version,
27
        'tested' => $tested,
28
        'author' => $author,
29
        'last_updated' => $last_updated,
30
        'banner_low' => $banner_low,
31
        'banner_high' => $banner_high,
32
        "package_url" => home_url( '/api/license-manager/v1/get?p=' . $product_id . '&e=' . $email . '&l=' . urlencode( $license_key ) ),
33
        "description_url" => get_permalink( $product->ID ) . '#v=' . $version
34
    );
35
}

Ligne 14: Récupérer les informations sur le produit à partir des métadonnées post.

Lignes 16-21: Collectez les données des champs de métadonnées.

Lignes 23-34: Construisez la réponse. Généralement, il s’agit simplement de placer les données des lignes 16 à 21 dans le tableau. Une ligne, la ligne 32, mérite cependant plus d'attention.

Ceci est pour le système de mise à jour WordPress que nous utiliserons dans le prochain tutoriel de la série. Pour faciliter la tâche à cette étape, l'action info renvoie une URL pointant sur l'autre action de l'API, get, avec tous les paramètres requis.

Étape 7: Testez l'action de l'API

Vous venez de créer la première de nos deux fonctions API. Si vous le souhaitez, vous pouvez tester la fonctionnalité en appelant la méthode API dans un navigateur Web. Assurez-vous simplement de configurer correctement les données avant de passer l'appel: il doit exister un produit et une licence pour cela dans le système pour que l'action de l'API fonctionne.

Un autre problème est que vous devrez encoder les paramètres de clé de licence de courrier électronique et de licence avant de les placer dans l'URL car ils contiennent des caractères spéciaux.

La sortie ressemblera un peu à ceci, selon ce que vous avez enregistré en tant que données de votre produit:

Stockage de fichiers dans Amazon S3

Avec la première moitié de l'API terminée, il est temps d'examiner la fonction de la deuxième API, get. Cette fonction API vérifiera la clé de licence en utilisant la même méthode que nous avons utilisée avec info, puis renverra le fichier téléchargeable.

Pour que l'action de l'API ait un sens, il est important que le téléchargement ne soit pas accessible sans clé de licence valide en contournant simplement l'API et en passant directement au fichier. Le service de stockage simple (S3) d'Amazon nous offre cette fonctionnalité facilement et à un prix abordable (presque gratuit pour la plupart des utilisateurs) tout en rendant le téléchargement fiable.

Dans les étapes suivantes, nous verrons tout d'abord comment télécharger les fichiers sur Amazon S3 à l'aide du tableau de bord en ligne AWS (Amazon Web Services). Ensuite, une fois le fichier téléchargé, nous ajouterons la fonctionnalité de téléchargement à notre API.

Si vous utilisez déjà Amazon S3 et savez vous y retrouver, vous pouvez passer directement à la section suivante et commencer à mettre en œuvre l'action get. Si vous êtes nouveau sur S3, lisez la suite.

Étape 1: Créer un compte

La création d'un compte AWS est bien documentée, mais elle comporte de nombreuses étapes, passons donc rapidement en revue.

Tout d’abord, allez à aws.amazon.com et cliquez sur "Inscription" dans le coin supérieur droit.

Dans l'écran suivant, vous avez la possibilité de créer un nouveau compte Amazon ou d'utiliser un compte existant que vous avez utilisé pour d'autres services Amazon (par exemple, le magasin en ligne lui-même):

Le choix vous appartient: si vous décidez de créer un nouveau compte, cela se fera ensuite. Si vous utilisez votre compte existant, le flux entre directement dans le processus en cinq étapes de configuration de votre compte AWS. Lors de l’enregistrement, il vous sera demandé de saisir les informations de votre carte de crédit. Pour les utilisations les plus courantes, vous n’aurez plus à vous soucier du prix.

Après avoir entré vos informations de carte de crédit, avant que votre compte soit accepté, vous devrez vérifier votre numéro de téléphone. Amazon appelle automatiquement votre numéro de téléphone et vous invite à saisir le code à quatre chiffres affiché à l'écran. Lorsque je l'ai réessayé en écrivant ce tutoriel, j'ai eu du mal à saisir le code avec le clavier de l'iPhone. Cependant, dire les chiffres à voix haute un par un a parfaitement fonctionné.

La dernière étape consiste à choisir un plan de soutien. Je vous suggère de choisir l'option gratuite pour le moment. Il n’ya vraiment pas beaucoup de besoins de support pour S3 et vous pouvez reconsidérer cette option si vous décidez d’utiliser les fonctionnalités plus avancées.

Maintenant que vous avez créé et activé votre compte, ajoutons un fichier.

Étape 2: Créer un seau

Lancez la console de gestion AWS et choisissez S3 dans l'écran des options:

L'administrateur AWS propose de nombreuses fonctionnalités, mais vous pouvez ignorer le reste pour l'instant (ce sont des fonctionnalités avancées dont la plupart des développeurs WordPress n'auront jamais besoin - je n'utilise moi-même que S3 et EC2).

Maintenant que vous êtes dans la console d'administration S3, commencez par créer un compartiment. Un compartiment est un conteneur de niveau supérieur pour vos fichiers S3 pouvant contenir des dossiers et des fichiers. Voici comment la documentation AWS décrit le concept:

Chaque objet que vous stockez dans Amazon S3 réside dans un compartiment. Vous pouvez utiliser des compartiments pour regrouper des objets liés de la même manière que vous utilisez un répertoire pour regrouper des fichiers dans un système de fichiers. Les compartiments ont des propriétés, telles que les autorisations d'accès et le statut de la gestion des versions, et vous pouvez spécifier la région dans laquelle vous souhaitez qu'ils résident.

Donnez à votre panier un nom composé de lettres minuscules (a-z), de chiffres, de tirets et de points (pour des informations plus détaillées, consultez la documentation) et cliquez sur "Créer".

Si vous le souhaitez, vous pouvez également choisir une région dans laquelle stocker vos fichiers. Il est cependant parfaitement acceptable de laisser le paramètre à son option par défaut.

Une fois que vous avez créé le compartiment, vous verrez une vue du navigateur de fichiers avec ce compartiment créé:

Dans cet écran, vous pouvez créer autant de nouveaux compartiments que vous le souhaitez. Pour l'instant, un suffit. Cliquez sur le nom du compartiment pour y ajouter des fichiers.

Étape 3: Télécharger le fichier

Le compartiment que nous venons de créer contiendra les téléchargements pour votre installation de gestionnaire de licence. Nous ne créerons pas les thèmes et les plugins téléchargeables avant la troisième et dernière partie du didacticiel. Pour les tests, créez simplement un fichier zip contenant quelque chose (par exemple un fichier texte).

Cliquez sur le bouton Upload dans le coin supérieur gauche de l'écran d'administration S3. Un écran de téléchargement apparaît:

Choisissez Ajouter des fichiers pour sélectionner le ou les fichiers à télécharger. Puis cliquez sur Start Upload.

Nous pourrions utiliser Définir les détails pour définir les autorisations de fichiers, mais comme nous ne souhaitons pas rendre le téléchargement accessible au public, les options par défaut sont exactement ce que nous voulons.

Une fois le fichier téléchargé, vous le verrez dans votre compartiment:

Fermez la fenêtre de transfert en cliquant sur la croix dans le coin supérieur droit. Puis sélectionnez le fichier et choisissez Propriétés dans le menu en haut à droite:

Dans cet écran, vous pouvez toujours modifier les autorisations du fichier et d’autres paramètres. Vous trouverez également l'URL du fichier dans les informations. Copiez le lien et ouvrez-le dans un navigateur pour tester ce qui se passe lorsque vous essayez de télécharger le fichier.

Si tout est correctement configuré, vous ne pouvez pas le faire: même si un visiteur au hasard connaissait l'URL exacte de votre fichier téléchargé, il ne pourra pas le télécharger en ignorant la vérification de la licence dans l'appel de l'API.

Si vous voyez une erreur comme celle-ci, tout est configuré correctement et vous pouvez commencer à créer le code pour télécharger ce fichier:

Comme dernière étape avant de coder davantage, créez un produit dans WordPress en utilisant notre plugin de gestionnaire de licence (ou mettez à jour un existant) et ajoutez les informations du fichier téléchargé:

Servir le téléchargement depuis S3

Maintenant que vous avez chargé avec succès un fichier sur Amazon S3, demandons à l'API du gestionnaire de licences de renvoyer le fichier à la demande, mais uniquement si la licence de l'utilisateur est valide.

Pour ce faire, nous allons renseigner l'espace réservé aux actions d'API que nous avons ajouté à notre fonction de traitement des API, handle_request, plus haut dans ce didacticiel. L'action vérifie d'abord la licence à l'aide de verify_license_and_execute, puis utilise la bibliothèque AWS officielle d'Amazon pour créer et renvoyer un lien de téléchargement signé vers le fichier téléchargeable du produit.

Étape 1: Téléchargez et incluez la bibliothèque AWS

Pour commencer, commencez par télécharger le kit AWS SDK for PHP d'Amazon.

Il y a plusieurs façons d'inclure le SDK dans votre projet, mais je suggère d'utiliser le téléchargement zip dans ce projet même s'il est déjà un peu démodé: Le SDK contient des fonctionnalités permettant d'utiliser toutes les fonctionnalités AWS - comme vous l'avez vu précédemment, il y en a beaucoup - et nous n'en utilisons qu'un, S3. Télécharger la version zip et l'inclure manuellement dans votre projet vous donne la possibilité de supprimer tous les fichiers supplémentaires qui occupent seulement de l'espace dans le téléchargement du plugin.

Une fois le SDK AWS téléchargé, créez un répertoire appelé lib dans le répertoire wp-license-manager. À l'intérieur, créez un répertoire appelé aws contenant le contenu du package zip du SDK.

Maintenant, si vous voulez, vous pouvez couper le contenu du répertoire, en ne laissant que les répertoires Common et S3 à l'intérieur de Aws. Si la taille du plug-in n'est pas un problème, vous pouvez également ignorer cette étape et laisser le SDK tel qu'il est.

Ensuite, connectez le kit SDK AWS au plug-in WP License Manager au niveau du code.

Le SDK utilise des espaces de noms, une fonctionnalité PHP qui n’a été ajoutée qu’en PHP 5.3. La configuration PHP officielle requise pour WordPress est 5.2.6; l’utilisation du SDK ne fonctionnera donc pas pour tous les utilisateurs de WordPress.

Une façon de contourner cette limitation consiste à utiliser une bibliothèque S3 tierce ou à en écrire une vous-même. Cependant, comme le SDK officiel est la méthode la plus recommandée en général, allons-y cette fois-ci. Dans la version du plugin publiée dans le référentiel de plugins WordPress, j'ai inclus à la fois la version du kit SDK AWS et une version de secours utilisant cette bibliothèque S3 autonome. Le plugin choisit le bon à utiliser au moment de l'exécution, en fonction de la version PHP du système sur lequel le plugin est exécuté.

Dans ce didacticiel, cependant, nous allons simplifier un peu les choses et n’avoir qu’une version du SDK AWS.

Créez une nouvelle classe, Wp_License_Manager_S3 et placez-la dans le répertoire includes du plugin:

1
<?php
2
/**

3
 * A wrapper for our Amazon S3 API actions.

4
 *

5
 * @package    Wp_License_Manager

6
 * @subpackage Wp_License_Manager/includes

7
 * @author     Jarkko Laine <jarkko@jarkkolaine.com>

8
 */
9
class Wp_License_Manager_S3 {
10
11
}

Pour inclure la classe dans le projet, ajoutez les lignes suivantes à la fonction load_dependencies de la classe Wp_License_Manager:

1
/**

2
 * A wrapper class for our Amazon S3 connectivity.

3
 */
4
require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wp-license-manager-s3.php';
5
require_once plugin_dir_path( dirname( __FILE__ ) ) . 'lib/aws/aws-autoloader.php';

La première ligne require inclut la classe d'encapsuleur créée ci-dessus et la seconde inclut l'autoloader du kit SDK AWS, un élément de code chargé d'exiger les fichiers source du kit SDK en fonction des besoins.

Étape 2: Créer la fonction pour générer le lien de téléchargement

Dans la classe Wp_License_Manager_S3 que vous venez de créer, ajoutez la fonction suivante pour générer un lien de téléchargement signé pouvant être utilisé pour télécharger le fichier protégé à partir d'Amazon S3:

1
/**

2
 * Returns a signed Amazon S3 download URL.

3
 *

4
 * @param $bucket       string  Bucket name

5
 * @param $file_name    string  File name (URI)

6
 * @return string       The signed download URL

7
 */
8
public static function get_s3_url( $bucket, $file_name ) {
9
    $options = get_option( 'wp-license-manager-settings' );
10
11
    $s3_client = Aws\S3\S3Client::factory(
12
        array(
13
            'key'    => $options['aws_key'],
14
            'secret' => $options['aws_secret']
15
        )
16
    );
17
18
    return $s3_client->getObjectUrl( $bucket, $file_name, '+10 minutes' );
19
}

Passons en revue la fonction pour voir ce que fait id:

Lignes 11 à 16: Créez une instance de classe client Amazon S3 pour créer le lien de téléchargement. Le SDK nécessite des informations d'identification de sécurité AWS, que nous stockons dans les options WordPress, à l'aide d'un écran de paramètres que nous allons créer à l'étape suivante.

Ligne 18: Utilisez le SDK pour générer un lien de téléchargement pour le compartiment et le nom de fichier donnés. Le lien de téléchargement sera valide pendant 10 minutes à partir de ce moment afin que l’utilisateur ait le temps de commencer le téléchargement.

Étape 3: Créer une page de paramètres pour les paramètres AWS

Comme vous l'avez remarqué à l'étape précédente, nous devons stocker une clé API AWS et un secret dans les options WordPress afin que le plug-in puisse être configuré pour être utilisé avec différents comptes AWS.

Pour ce faire, utilisons l'API Settings. La création d’une page de paramètres à l’aide de l’API de paramètres comprend trois étapes: initialisation des champs de paramètres, ajout de la page de paramètres et définition des fonctions de rendu des différents éléments de la page de paramètres.

Tout commence en ajoutant deux actions, une pour admin_init et une pour admin_menu:

1
// Plugin settings menu$this->loader->add_action( 'admin_init', $plugin_admin, 'add_plugin_settings_fields');$this->loader->add_action( 'admin_menu', $plugin_admin, 'add_plugin_settings_page');

Maintenant que vous avez ajouté les actions, créez les fonctions pour les gérer. Ils doivent tous deux être ajoutés à la classe Wp_License_Manager_Admin.

Tout d’abord, ajoutez la fonction add_plugin_settings_fields qui initialisera une section de paramètres, puis deux champs de paramètres pour l’intégrer:

1
/**

2
 * Creates the settings fields for the plugin options page.

3
 */
4
public function add_plugin_settings_fields() {
5
    $settings_group_id = 'wp-license-manager-settings-group';
6
    $aws_settings_section_id = 'wp-license-manager-settings-section-aws';
7
    $settings_field_id = 'wp-license-manager-settings';
8
9
    register_setting( $settings_group_id, $settings_field_id );
10
11
    add_settings_section(
12
        $aws_settings_section_id,
13
        __( 'Amazon Web Services', $this->plugin_name ),
14
        array( $this, 'render_aws_settings_section' ),
15
        $settings_group_id
16
    );
17
18
    add_settings_field(
19
        'aws-key',
20
        __( 'AWS public key', $this->plugin_name ),
21
        array( $this, 'render_aws_key_settings_field' ),
22
        $settings_group_id,
23
        $aws_settings_section_id
24
    );
25
26
    add_settings_field(
27
        'aws-secret',
28
        __( 'AWS secret', $this->plugin_name ),
29
        array( $this, 'render_aws_secret_settings_field' ),
30
        $settings_group_id,
31
        $aws_settings_section_id
32
    );
33
}

Lignes 5-7: Initialisez trois variables avec les noms du champ de réglage et des noms de section. Cela nous aide à ne pas insérer de fautes de frappe ...

Ligne 9: Enregistrez l'élément de configuration 'wp-license-manager-settings'. Ce sera un tableau dans lequel les deux paramètres, aws-key et aws-secret seront stockés.

Lignes 11 à 16: Ajoutez la section des paramètres qui contiendra les deux champs de paramètres.

Lignes 18-32: Ajoutez nos deux champs de paramètres (aws-key et aws-secret), en les plaçant dans la section des paramètres créée aux lignes 11 à 16.

Maintenant, ajoutez la deuxième fonction, add_plugin_settings_page. Cette fonction créera la page des paramètres en tant qu'enfant du menu principal Paramètres, à l'aide de la fonction add_options_page.

1
/**

2
 * Adds an options page for plugin settings.

3
 */
4
public function add_plugin_settings_page() {
5
    add_options_page(
6
        __( 'License Manager', $this->plugin_name ),
7
        __( 'License Manager Settings', $this->plugin_name ),
8
        'manage_options',
9
        'wp-license-settings',
10
        array( $this, 'render_settings_page' )
11
    );
12
}

Chacun des éléments de l'API de paramètres ci-dessus (la page de paramètres, la section de paramètres et les deux champs de paramètres) prend une fonction de rendu en tant que paramètre.

Pour terminer la configuration de la page de paramètres, créez les fonctions d’affichage suivantes:

1
/**

2
 * Renders the plugin's options page.

3
 */
4
public function render_settings_page() {
5
    $settings_group_id = 'wp-license-manager-settings-group';
6
    require plugin_dir_path( dirname( __FILE__ ) ) . 'admin/partials/settings_page.php';
7
}
8
9
/**

10
 * Renders the description for the AWS settings section.

11
 */
12
public function render_aws_settings_section() {
13
    // We use a partial here to make it easier to add more complex instructions

14
    require plugin_dir_path( dirname( __FILE__ ) ) . 'admin/partials/aws_settings_group_instructions.php';
15
}
16
17
/**

18
 * Renders the settings field for the AWS key.

19
 */
20
public function render_aws_key_settings_field() {
21
    $settings_field_id = 'wp-license-manager-settings';
22
    $options = get_option( $settings_field_id );
23
    ?>
24
        <input type='text' name='<?php echo $settings_field_id; ?>[aws_key]' value='<?php echo $options['aws_key']; ?>' class='regular-text'>
25
    <?php
26
}
27
28
/**

29
 * Renders the settings field for the AWS secret.

30
 */
31
public function render_aws_secret_settings_field() {
32
    $settings_field_id = 'wp-license-manager-settings';
33
    $options = get_option( $settings_field_id );
34
    ?>
35
       <input type='text' name='<?php echo $settings_field_id; ?>[aws_secret]' value='<?php echo $options['aws_secret']; ?>' class='regular-text'>
36
    <?php
37
}

Les fonctions de rendu du champ de paramètres render_aws_key_settings_field et render_aws_secret_settings_field sont essentiellement des copies les unes des autres: elles récupèrent d'abord les options du plugin, puis impriment un champ de texte avec le nom du paramètre et sa valeur actuelle.

Les fonctions de rendu de la page de paramètres (render_settings_page) et de la section de paramètres (render_aws_settings_section) sont similaires, mais au lieu d’imprimer le code HTML dans la fonction, elles utilisent des modèles HTML distincts. Ce n'est en aucun cas la seule façon de le faire - j'ai choisi cette approche, car ces fonctions rendent un peu plus le code HTML et il peut être nécessaire de l'étendre ultérieurement.

Voici ce qui se passe dans les modèles. Tout d’abord, admin/partials/settings_page.php, le partiel de la page des paramètres:

1
<?php
2
/**

3
 * The view for the plugin's options page.

4
 *

5
 * @package    Wp_License_Manager

6
 * @subpackage Wp_License_Manager/admin/partials

7
 */
8
?>
9
10
<div class="wrap">
11
    <div id="icon-edit" class="icon32 icon32-posts-post"></div>
12
13
    <h2>
14
        <?php _e( 'WP License Manager Settings', $this->plugin_name ); ?>
15
    </h2>
16
17
    <form action='options.php' method='post'>
18
        <?php
19
        settings_fields( $settings_group_id );
20
        do_settings_sections( $settings_group_id );
21
        submit_button();
22
        ?>
23
    </form>
24
</div>

La partie intéressante se trouve à la fin du fichier PHP, où nous créons le formulaire et insérons les champs de paramètres, les sections et le bouton d'envoi.

Le partiel de la section des paramètres (admin/partials/aws_settings_group_instructions.php) est actuellement presque vide et affiche une courte ligne d'instructions:

1
<?php
2
/**

3
 * The view for the AWS settings section's description on the plugin's settings page.

4
 *

5
 * @package    Wp_License_Manager

6
 * @subpackage Wp_License_Manager/admin/partials

7
 */
8
?>
9
10
<?php _e( 'Enter your AWS credentials below.', $this->plugin_name ); ?>

Maintenant, nous avons créé la page des paramètres. Visitez le tableau de bord WordPress pour le voir en action:

Étape 4: obtenez une clé et un secret d'API AWS

Pour tester la fonctionnalité, vous devez toujours récupérer une clé d'API et un secret d'AWS et les stocker dans les champs de paramètres que vous venez de créer.

Pour ce faire, revenez à la console d'administration AWS et cliquez sur votre nom dans le menu en haut à droite. Dans la liste déroulante qui s'affiche, choisissez Informations d'identification de sécurité.

Ensuite, vous verrez apparaître le popup suivant:

Sélectionnez l'option Démarrer avec les utilisateurs IAM. Ainsi, au lieu d'utiliser vos informations d'identification de sécurité globale partout, vous pouvez créer des noms d'utilisateur (et des informations d'accès) distincts pour toutes les utilisations AWS différentes que vous pourriez avoir.

Ensuite, créez un utilisateur à utiliser pour votre installation de WP License Manager.

Tout d'abord, cliquez sur Créer des utilisateurs en haut de la page. Ensuite, sur la page suivante, entrez un nom d’utilisateur qui vous convient (j’ai tout simplement utilisé test_user, mais une meilleure option serait probablement license-manager, ou quelque chose qui vous dira à quoi sert l’utilisateur) et cliquez sur Créer. .

L'utilisateur est créé et sur la page suivante, vous verrez ses informations d'identification de sécurité. Copiez-les et placez-les dans les paramètres que nous avons créés à l'étape précédente.

Étape 5: Créer la fonction API

Maintenant, nous avons construit toutes les pièces nécessaires à l'action get API. Mettons-les ensemble et créons l'action elle-même.

Tout d’abord, remplissez le bloc switch..case que nous avons laissé pour l’action get dans la fonction handle_request de Wp_License_Manager_API:

1
case 'get':
2
    $response = $this->verify_license_and_execute( array( $this, 'get_product' ), $params );
3
    break;

La fonction verify_license_and_execute est déjà terminée, il ne reste donc plus qu'à ajouter la fonction de gestionnaire get_product

Voici la fonction:

1
/**

2
 * The handler for the "get" request. Redirects to the file download.

3
 *

4
 * @param   $product    WP_Post     The product object

5
 */
6
private function get_product( $product, $product_id, $email, $license_key ) {
7
    // Get the AWS data from post meta fields

8
    $meta = get_post_meta( $product->ID, 'wp_license_manager_product_meta', true );
9
    $bucket = isset ( $meta['file_bucket'] ) ? $meta['file_bucket'] : '';
10
    $file_name = isset ( $meta['file_name'] ) ? $meta['file_name'] : '';
11
12
    if ( $bucket == '' || $file_name == '' ) {
13
        // No file set, return error

14
        return $this->error_response( 'No download defined for product.' );
15
    }
16
17
    // Use the AWS API to set up the download

18
    // This API method is called directly by WordPress so we need to adhere to its

19
    // requirements and skip the JSON. WordPress expects to receive a ZIP file...

20
21
    $s3_url = Wp_License_Manager_S3::get_s3_url( $bucket, $file_name );
22
    wp_redirect( $s3_url, 302 );
23
}

Passons en revue la fonction pour voir ce qu'elle fait:

Lignes 7 à 10: lisez les paramètres de compartiment et de nom de fichier à partir des métadonnées du produit.

Lignes 12-15: Si les métadonnées ne sont pas définies, retournez une réponse d'erreur.

Ligne 21: Utilisez le kit AWS SDK pour créer une URL signée pour le fichier téléchargeable du produit demandé.

Ligne 22: redirection vers l'URL de téléchargement signée dans S3. Comme nous le verrons à la prochaine étape du didacticiel, WordPress s'attend à ce que cette demande renvoie le fichier lui-même. Nous devons donc détourner un peu de notre API basée sur JSON et faire ce qui fonctionne le mieux pour WordPress.

Vous avez maintenant terminé de créer le plug-in du gestionnaire de licences. Si vous le souhaitez, vous pouvez tester le téléchargement de la même manière que nous avions précédemment testé la demande d’informations pour vérifier si tout fonctionnait correctement. Au lieu d’indiquer l’erreur constatée lors de l’accès direct au fichier sur S3, votre navigateur télécharge le fichier zip que vous avez chargé. à S3.

Conclusion

L'API terminée, nous avons maintenant terminé le plug-in du gestionnaire de licences. Bien que de nombreuses fonctionnalités puissent être ajoutées, la version actuelle est entièrement fonctionnelle et peut être utilisée pour gérer les licences avec succès.

Dans la prochaine et dernière partie de la série de didacticiels, nous allons tout rassembler et créer un thème et un plug-in WordPress à l’aide de notre serveur de gestionnaire de licence pour rechercher les mises à jour.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.