Table des matières
- Selling Pay-Per-Download Products - Vendre des produits à télécharger (dématérialisés)
- The buyer experience -- L'expérience client
- Setting up the product and permission structure -- Mise en oeuvre du produit et des permissions
- Payment process -- Processus de paiement
- Extension: Assigning permissions upon purchase part 1 -- Extension: assignation des droits à l'achat (partie 1)
- Pay-per-download extension part 2 -- Extension Pay-per-download (partie 2)
- Confirmation e-mails and pages -- Mails et pages de confirmation
- Extra considerations -- Considérations complémentaires
- Paypal Sandbox : comptes de test et devises
- Modification pour eZ Publish 4.3+
Pay-per-download extension part 2 -- Extension Pay-per-download (partie 2)
Date de publication: le vendredi 28 janvier 2011 à 00h52
Dernière modification: par Pascal BOYER le mardi 29 mars 2011 à 16h16
Versions: 4.x
Workflow code in the "execute" function / Code du workflow dans la fonction execute
Now we will program the heart of our workflow extension, using the eZ Publish API and the variables that were passed to the "execute" function (in eventtypes/events/payperdownload/payperdownloadtype.php in your extension) to perform the role assignment(s). The process of writing this code from scratch would involve browsing through the API and piece by piece code testing (using functions like var_dump(), die(), eZExecution::cleanExit() as needed), which we will not delve into. However, if you are a relative beginner to the eZ Publish API, it is worth browsing through the class lists and definitions to see all that is possible, as you have even more possibilities when you're calling eZ Publish classes in PHP land than with eZ Publish template operators. The classes are named intuitively, and the methods are grouped well and explained in quite a lot of detail. Be sure to take the time to explore the classes, methods, and attributes used in this article.
Nous allons à présent écrire le cœur de notre extension en utilisant
l'API eZ Publish
et les variables qui ont été passées à la fonction execute (dans le fichier eventtypes/events/payperdownload/payperdownloadtype.php de votre extension) afin de réaliser l'assignation(s) du rôle. La procédure de rédaction de ce code à partir de zéro impliquerait de parcourir l'API pour tester du code, morceau par morceau (en utilisant les fonctions var_dump(), die(),
eZExecution::cleanExit()
en fonction de nos besoin). Mais nous ne détaillerons pas ici cette procédure. Cependant, si vous êtes relativement débutant dans l'utilisation de l'API eZ Publish, il serait bon que vous parcourriez les listes de classes et de définitions pour vous faire une idée de tout ce qu'il est possible de réaliser, les classes eZ Publish du monde PHP vous offrant bien plus de possibilités que les opérateurs de templates eZ Publish. Le nom des classes est intuitif/explicite et les méthodes, bien regroupées, sont expliquées avec force détails. Prenez au moins le temps d'explorer les classes, les méthodes et les attributs utilisés dans cet article.
Role assignment(s) / Assignation du rôle
The last part of our code is where we will start. Before the workflow is accepted and finished running, we do the actual role assignment(s) using the eZRole::assignToUser method:
Notre dernier bout de code constitue notre point de départ. Avant que le workflow ne soit accepté et que son exécution ne s'achève, nous réalisons l'assignation(s) du rôle grâce à la méthode
eZRole::assignToUser
.
$role = eZRole::fetch( $roleID ); $role->assignToUser( $userID, $limitIdentifier, $limitValue); eZRole::expireCache();
The first line creates an eZRole object when supplied a role ID. The second line assigns that role to a specified user, with a given limitation type ("Subtree" or "Section"; this will be "Subtree" in our case), and the actual limitation value, which is a path of node IDs to the download file. The last line clears the role cache.
La première ligne crée un
objet eZRole
lorsqu'un ID de rôle est fourni. La seconde ligne assigne ce rôle à un utilisateur en particulier en tenant compte du type de limitation (Sous-arborescence ou Section, ce sera Sous-arborescence dans notre cas) et de sa valeur qui correspond à un chemin de ID de nœuds menant au fichier de téléchargement. La dernière ligne vide le cache du rôle.
There is quite a bit more code to go, but it is all related to supplying the correct values for the variables used in the parameters above:
Il reste encore un peu de code à écrire, mais il est entièrement dédié à pourvoir les valeurs correctes aux variables utilisées dans les paramètres ci-dessus:
- role ID / ID du rôle
- user ID / ID de l'utilisateur
- limitation type / Type de limitation
- limitation value (the limitation value being the most involved to find) / Valeur de la limitation (cette valeur étant la plus complexe à trouver)
INI and other basic settings / Les fichiers de configuration et autres paramètres de base
There are a few variables that will be consistent for every pay-per-download role assignment. We can define these in an INI file and then call those values in our workflow event. In settings/payperdownload.ini within your extension, enter the following:
Certaine variables resteront cohérentes (???) pour chaque assignation de rôle. Nous pouvons définir celles-ci dans un fichier INI et donc appeler ces valeurs dans notre événement de workflow. Ajoutez le code ci-dessous dans le fichier settings/payperdownload.ini de votre extension:
<?php /* #?ini charset="utf-8"? [PayPerDownloadSettings] # Which role contains the policy for pay-per-download? RoleID=6 # Which content classes (by identifier) contain pay-per-download files? ContentClasses[] ContentClasses[]=product # Which attribute (by identifier) of the above class contains the pay-per-download file? Attributes[] Attributes[product]=download */ ?>
If you used the same basic Website Interface install that this article used, your "Pay per download" role with have an ID of 6. Be sure to double check what the relevant role ID is on your installation by viewing the role in the Administration Interface. The URL should end in "role/view/<role_id>".
Si vous utilisez également une installation Website Interface standard alors le rôle Paiement-au-telechargement devrait avoir le ID=6. Contrôlez la valeur du ID de ce rôle sur votre installation à partir de l'interface d'édition des rôles dont l'URI doit se terminer par role/view/<role_id>.
We will access these settings, as well as define the limitation type and user ID, near the top of our "execute" function. Our function should now look like this:
Nous accèderons à ces paramètres et définirons le type de limitation ainsi que le ID de l'utilisateur au début de notre fonction execute qui doit à présent ressembler à ceci (eventtypes/events/payperdownload/payperdownloadtype.php de votre extension):
public function execute( $process, $event ) { $ini = eZINI::instance( 'payperdownload.ini' ); // Which role contains the policy for pay-per-download? $roleID = $ini->variable( 'PayPerDownloadSettings', 'RoleID' ); // Which content class (by identifier) contains the pay-per-download file? $contentClasses = $ini->variable( 'PayPerDownloadSettings', 'ContentClasses' ); // Which attribute (by identifier) of the above class contains the pay-per-download file? // Note that this is in an array because later we will pass it to fetchAttributesByIdentifier $attributes = $ini->variable( 'PayPerDownloadSettings', 'Attributes' ); // We want the limit identifier to be by subtree $limitIdentifier = 'Subtree'; // Get the current user $userID = $process->UserID; /* Not going to use these yet // Create the role object $role = eZRole::fetch( $roleID ); // Assign the role $role->assignToUser( $userID, $limitIdentifier, $limitValue); // Clear the role cache eZRole::expireCache(); */ return eZWorkflowType::STATUS_ACCEPTED;
Note the appropriate calls to create an instance of our INI file and to access the variables within the INI file. We were also able to access the user ID from the $process object, which is supplied as part of the standard workflow event framework.
Notez les appels appropriés pour
créer une instance de notre fichier INI
et pour
accéder aux variables du fichier INI
. Nous pouvons également accéder au ID de l'utilisateur depuis l'objet $process qui est fourni par le framework standard de l'événement.
From the list of variables that we need to do the role assignment, we are left with the undefined limitation value.
De toutes les variables dont nous avons besoin pour réaliser l'assignation du rôle il reste la valeur de la limitation qui est encore indéfinie.
Getting the limitation value / Obtenir la valeur de la limitation
Recall the the limitation value will be a path of node IDs to the download file, so that the user can download the file associated with each product. Let's take a moment to map out how we are going to get that path:
Souvenez-vous que la valeur de la limitation consiste en un chemin de ID de nœuds menant au fichier de téléchargement afin que l'utilisateur puisse télécharger le ficher associer au produit. Prenons quelques instants pour voir comment nous allons obtenir ce chemin:
-
Access the current order information
Accéder aux informations de l'achat courant -
Find out what products were purchased
Déterminer quels produits ont été achetés -
Find out which (if any) products are of the classes for downloadable products
Déterminer quel produits sont des instances de la classe permettant de créer des produits téléchargeables -
Loop through the relevant products and access the file associated with each product
Lister les produits pour accéder au fichier associé à chaque produit -
Find out the node ID path for each file
Déterminer le chemin de l'ID du noeud pour chaque fichier.
Information about the current order is also available in the already supplied $process object, as you will see below. The rest of the code is explained within the comments.
Les informations sur l'achat courant sont également disponibles dans l'objet $process déjà fourni, comme vous le verrez plus bas. Le reste du code est expliqué dans les commentaires:
[...] // Get the current user $userID = $process->attribute( 'user_id' ); // Get the order ID so that we can find out what objects there were $parameters = $process->attribute( 'parameter_list' ); $orderID = $parameters['order_id']; // Get the order $thisOrder = eZOrder::fetch( $orderID ); // Create the role object $role = eZRole::fetch( $roleID ); // Loop through each product to see whether it's relevant for role assignment foreach ($thisOrder->productItems() as $thisProduct) { $classIdentifier = $thisProduct["item_object"]->ContentObject->attribute( 'class_identifier' ); // Is this in the list of downloadable products? if( in_array( $classIdentifier, $contentClasses ) ) { // We have a match, so the last thing we need to do is to fetch the node of the file // First we want to grab the object so that we can get at its attributes $thisObject = $thisProduct["item_object"]->ContentObject; $dataMap = $thisObject->fetchAttributesByIdentifier( array( $attributes[$classIdentifier] ) ); // There should only be one $dataMap item, so get the path of that foreach( $dataMap as $dataMapAttribute) { $node = eZContentObjectTreeNode::fetchByContentObjectID($dataMapAttribute->attribute( 'data_int' ); // We're only after the main node $limitValue = $node[0]->attribute( 'path_string' ); } // Assign the role $role->assignToUser( $userID, $limitIdentifier, $limitValue); } } // Clear the role cache eZRole::expireCache(); [...]
The additional API code used above involves the following classes:
Le code supplémentaire de l'API utilisé ci-dessus fait appel aux classes suivantes:
-
eZOrder
: to fetch the order, and fetch the product items, which gave us eZContentObject objects
pour rechercher la commande, les produits et nous fournir les objets eZContentObject -
eZContentObject
: to find out whether the class identifier for each product matched the list of defined downloadable products (although in our example every product would have a downloadable file); and to access the "Download file" attribute to get at the relevant file node(s)
pour déterminer si l'identifiant de classe de chaque produit correspond à la liste des produits téléchargeables (bien que dans notre exemple chaque produit devrait être lié à un fichier téléchargeable) et pour accéder à l'attribut Télécharger le fichier pour atteindre les nœuds des fichiers. -
eZContentObjectTreeNode
: to access the path to the relevant file node(s)
pour accéder au chemin des nœuds des fichiers
Notice that the limitation value for each downloadable file is finally defined here:
Notez que la valeur de la limitation pour chaque fichier téléchargeable est définie ici:
// We're only after the main node $limitValue = $node[0]->attribute( 'path_string' );
The role assignment is then performed for each downloadable file.
L'assignation du rôle est donc réalisée pour chaque fichier téléchargeable.
Testing the complete workflow event code / Tester l'intégralité du code de l'événement
Your complete "execute" function should now look like this:
Votre fonction execute doit au final ressembler à ceci:
public function execute( $process, $event ) { $ini = eZINI::instance( 'payperdownload.ini' ); // Which role contains the policy for pay-per-download? $roleID = $ini->variable( 'PayPerDownloadSettings', 'RoleID' ); // Which content class (by identifier) contains the pay-per-download file? $contentClasses = $ini->variable( 'PayPerDownloadSettings', 'ContentClasses' ); // Which attribute (by identifier) of the above class contains the pay-per-download file? // Note that this is in an array because later we will pass it to fetchAttributesByIdentifier $attributes = $ini->variable( 'PayPerDownloadSettings', 'Attributes' ); // We want the limit identifier to be by subtree $limitIdentifier = 'Subtree'; // Get the current user $userID = $process->attribute( 'user_id' ); // Get the order ID so that we can find out what objects there were $parameters = $process->attribute( 'parameter_list' ); $orderID = $parameters['order_id']; // Get the order $thisOrder = eZOrder::fetch($orderID); // Create the role object $role = eZRole::fetch( $roleID ); // Loop through each product to see whether it's relevant for role assignment foreach ($thisOrder->productItems() as $thisProduct) { $classIdentifier = $thisProduct["item_object"]->ContentObject->attribute( 'class_identifier' ); // Is this in the list of downloadable products? if( in_array( $classIdentifier, $contentClasses ) ) { // We have a match, so the last thing we need to do is to fetch the node of the file // First we want to grab the object so that we can get at its attributes $thisObject = $thisProduct["item_object"]->ContentObject; $dataMap = $thisObject->fetchAttributesByIdentifier( array( $attributes[$classIdentifier] ) ); // There should only be one $dataMap item, so get the path of that foreach( $dataMap as $dataMapAttribute) { $node = eZContentObjectTreeNode::fetchByContentObjectID( $dataMapAttribute->attribute( 'data_int' ) ); // We're only after the main node $limitValue = $node[0]->attribute( 'path_string' ); } // Assign the role $role->assignToUser( $userID, $limitIdentifier, $limitValue); } } // Clear the role cache eZRole::expireCache(); return eZWorkflowType::STATUS_ACCEPTED; }
You can now test your workflow event by buying the book product you created. Use the "Test User" account on the front-end, add the product to your shopping cart, initiate the checkout process, then pay for the product using your PayPal Sandbox test buyer account. Then, log in to the Administration Interface using your Administrator user account, navigate to the "Pay-per-download" role, and see that it has been assigned correctly. The "Test User" should be using the "Pay-per-download" role, limited to the download file.
Vous pouvez à présent tester votre événement en achetant le livre que vous avez créé. Pour cela utilisez le compte Utilisateur De test, ajoutez le produit à votre panier, démarrer le processus de commande puis payez le livre en utilisant le compte de test buyer de Paypal Sandbox. Connectez-vous alors à l'interface d'administration de votre site en tant qu'administrateur, affichez le rôle Telechargement-apres-paiement et constatez qu'il a été assigné correctement: l'utilisateur Utilisateur De test devrait être lié à ce rôle et limité au fichier de téléchargement:
You can also test this by seeing if the Test User account can access "yoursite.com/Media/Downloads/eZ-Publish-Advanced-Content-Management-PDF".
Vous pouvez aussi procéder à ce test en contrôlant que le compte Utilisateur De test a bien accès au fichier votresite.com/Media/Telechargement/constitution-1791.
Table des matières
- Selling Pay-Per-Download Products - Vendre des produits à télécharger (dématérialisés)
- The buyer experience -- L'expérience client
- Setting up the product and permission structure -- Mise en oeuvre du produit et des permissions
- Payment process -- Processus de paiement
- Extension: Assigning permissions upon purchase part 1 -- Extension: assignation des droits à l'achat (partie 1)
- Pay-per-download extension part 2 -- Extension Pay-per-download (partie 2)
- Confirmation e-mails and pages -- Mails et pages de confirmation
- Extra considerations -- Considérations complémentaires
- Paypal Sandbox : comptes de test et devises
- Modification pour eZ Publish 4.3+














