diff options
author | Marcello Stanisci <marcello.stanisci@inria.fr> | 2016-01-20 18:15:46 +0100 |
---|---|---|
committer | Marcello Stanisci <marcello.stanisci@inria.fr> | 2016-01-20 18:15:46 +0100 |
commit | 44b4a0b20e798756826d7e3175e453b439e758dc (patch) | |
tree | 50e13f2b902f572979ec002fbd821d99fa01d2e2 | |
parent | 09b3cfee78cebd84cfec64ce28cd5d39be0a12d2 (diff) | |
download | merchant-44b4a0b20e798756826d7e3175e453b439e758dc.tar.gz merchant-44b4a0b20e798756826d7e3175e453b439e758dc.tar.bz2 merchant-44b4a0b20e798756826d7e3175e453b439e758dc.zip |
Adding most of blog-type website.
-rw-r--r-- | src/frontend/checkout.php | 2 | ||||
-rw-r--r-- | src/frontend_blog/README | 20 | ||||
-rw-r--r-- | src/frontend_blog/articles/essay-x.html | 19 | ||||
-rw-r--r-- | src/frontend_blog/blog_lib.php | 26 | ||||
-rw-r--r-- | src/frontend_blog/essay_checkout.php | 244 | ||||
-rw-r--r-- | src/frontend_blog/essay_contract.php | 78 | ||||
-rw-r--r-- | src/frontend_blog/essay_fulfillment.php | 20 | ||||
-rw-r--r-- | src/frontend_blog/essay_pay.php | 75 | ||||
-rw-r--r-- | src/frontend_blog/execute.js | 33 | ||||
-rw-r--r-- | src/frontend_blog/execute.php | 56 | ||||
-rw-r--r-- | src/frontend_blog/execute.tsx | 41 | ||||
-rw-r--r-- | src/frontend_blog/index.html | 79 | ||||
-rw-r--r-- | src/frontend_blog/style.css | 123 | ||||
-rw-r--r-- | src/frontend_blog/teaser.php | 46 | ||||
-rw-r--r-- | src/frontend_lib/merchants.php | 91 |
15 files changed, 952 insertions, 1 deletions
diff --git a/src/frontend/checkout.php b/src/frontend/checkout.php index 21d4d8c4..cf789b11 100644 --- a/src/frontend/checkout.php +++ b/src/frontend/checkout.php @@ -237,7 +237,7 @@ function taler_wallet_unload_cb(aEvent) (as the extension may be loaded/enabled after the page was loaded) */ function signal_taler_wallet_onload() { - var eve = new Event('taler-checkout-probe'); + var eve = new Event('taler-probe'); document.dispatchEvent(eve); }; diff --git a/src/frontend_blog/README b/src/frontend_blog/README new file mode 100644 index 00000000..8cfb490f --- /dev/null +++ b/src/frontend_blog/README @@ -0,0 +1,20 @@ +This directory contains the files implementing the frontend of the new merchant architecture. + +Only tested on nginx. To run the website, it suffices to have all the .php and .html files +in the same directory, and having PHP (with the extension 'pecl_http' enabled) enabled. + +File |What implements +-------------------------------- +o index.html | The homepage. Here it is possible to decide how much donate + to whom you would like. + +o fake_wire_transfer.php | PHP script that takes the wire transfer request and passes it on + | to the /admin/add/incoming API of the demo-mint. + +o checkout.php | The "payment selection" that is the form + that allows the user to choose the payment method he wishes to use. + It also implements the request of certificate and trigger the certificate + viewer in the extension when it arrives in the customer's machine. + +o pay.php | Actual receiving of money, plus it gives back a "fullfillment" page + that informs the user of his well ended deal. diff --git a/src/frontend_blog/articles/essay-x.html b/src/frontend_blog/articles/essay-x.html new file mode 100644 index 00000000..48db9115 --- /dev/null +++ b/src/frontend_blog/articles/essay-x.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <title>Blog site demonstration</title> + <link rel="stylesheet" type="text/css" href="style.css"> +</head> +<body> + <div id="teaser"> + <p> + The x essay is + </p> + </div> + <div id="full-article"> + <p> + about something + </p> + </div> +</body> +</html> diff --git a/src/frontend_blog/blog_lib.php b/src/frontend_blog/blog_lib.php new file mode 100644 index 00000000..4238e993 --- /dev/null +++ b/src/frontend_blog/blog_lib.php @@ -0,0 +1,26 @@ +<?php + +/** + * Take a (article's) filename and return its + * teaser. It has the articles folder hardcoded + */ +function get_teaser($name){ + $content = file_get_contents("articles/$name.html"); + $doc = new DOMDocument(); + $doc->loadHTML($content); + $teaser = $doc->getElementById("teaser"); + return $teaser; +} + +/** + * Take a (article's) filename and return its + * DOM. It has the articles folder hardcoded + */ +function get_article($name){ + $content = file_get_contents("articles/$name.html"); + $doc = new DOMDocument(); + $doc->loadHTML($content); + return $doc; +} + +?> diff --git a/src/frontend_blog/essay_checkout.php b/src/frontend_blog/essay_checkout.php new file mode 100644 index 00000000..c013d7c5 --- /dev/null +++ b/src/frontend_blog/essay_checkout.php @@ -0,0 +1,244 @@ +<!DOCTYPE html> +<html> +<head> + <title>Blog - Payment method - Taler Demo</title> + <link rel="stylesheet" type="text/css" href="style.css"> + <script> + /* + @licstart The following is the entire license notice for the + JavaScript code in this page. + + Copyright (C) 2014,2015 GNUnet e.V. + + The JavaScript code in this page is free software: you can + redistribute it and/or modify it under the terms of the GNU + Lesser General Public License (GNU LGPL) as published by the + Free Software + Foundation, either version 3 of the License, or (at your option) + any later version. The code is distributed WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU LGPL for more details. + + As additional permission under GNU LGPL version 3 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU LGPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + @licend The above is the entire license notice + for the JavaScript code in this page. + */ + </script> +</head> +<body onload="signal_taler_wallet_onload()"> + + <header> + <div id="logo"> + <svg height="100" width="100"> + <circle cx="50" cy="50" r="40" stroke="darkcyan" stroke-width="6" fill="white" /> + <text x="19" y="82" font-family="Verdana" font-size="90" fill="darkcyan">S</text> + </svg> + </div> + + <h1>Blog - Select payment method</h1> + </header> + + <aside class="sidebar" id="left"> + </aside> + + <section id="main"> + <article> + + <h1>Select your payment method</h1> + + <p> + This is an example for a "checkout" page of a Web shop. + On the previous page, you have created the shopping cart + and decided which product to buy (i.e. which project to + donate KUDOS to). Now in this page, you are asked to + select a payment option. As Taler is not yet universally + used, we expect merchants will offer various payment options. + </p> + <p> + The page also demonstrates how to only enable (or show) the Taler + option if Taler is actually supported by the browser. For example, + if you disable the Taler extension now, the Taler payment option + will be disabled in the page. Naturally, you could also trivially + hide the Taler option entirely by changing the visibility instead. + </p> + <p> + Note that you MUST select Taler here for the demo to continue, + as the other payment options are just placeholders and not + really working in the demonstration. Also, it is of course + possible to ask the user to make this choice already on the + previous page (with the shopping cart), we just separated the + two steps to keep each step as simple as possible. + </p> + + <form name="tform" action="" method="POST"> + <div id="opt-form" align="left"><br> + <input type="radio" name="payment_system" value="lisa" + id="lisa-radio-button-id">Lisa</input> + <br/> + <input type="radio" name="payment_system" value="ycard">You Card</input> + <br/> + <input type="radio" name="payment_system" value="cardme">Card Me</input> + <br/> + <input type="radio" name="payment_system" value="taler" + id="taler-radio-button-id" disabled="true">Taler</input> + <br/> + <input type="button" onclick="pay(this.form)" value="Ok"></input> + </div> + </form> + + </article> + </section> + +<script type="text/javascript"> + +/* This function is called from "taler_pay" after + we downloaded the JSON contract from the merchant. + We now need to pass it to the extension. */ +function handle_contract(json_contract) +{ + var cEvent = new CustomEvent('taler-contract', { detail: json_contract }); + + document.dispatchEvent(cEvent); +}; + + +/* Trigger Taler contract generation on the server, and pass the + contract to the extension once we got it. */ +function taler_pay(form) +{ + var contract_request = new XMLHttpRequest(); + + /* Note that the URL we give here is specific to the Demo-shop + and not required by the protocol: each web shop can + have its own way of generating and transmitting the + contract, there just must be a way to get the contract + and to pass it to the wallet when the user selects 'Pay'. */ + contract_request.open("GET", "essay_contract.php", true); + contract_request.onload = function (e) + { + if (contract_request.readyState == 4) + { + if (contract_request.status == 200) + { + /* display contract_requestificate (i.e. it sends the JSON string + to the extension) alert (contract_request.responseText); */ + console.log("response text:", contract_request.responseText); + handle_contract(contract_request.responseText); + } + else + { + /* There was an error obtaining the contract from the merchant, + obviously this should not happen. To keep it simple, we just + alert the user to the error. */ + alert("Failure to download contract from merchant " + + "(" + contract_request.status + "):\n" + + contract_request.responseText); + } + } + }; + contract_request.onerror = function (e) + { + /* There was an error obtaining the contract from the merchant, + obviously this should not happen. To keep it simple, we just + alert the user to the error. */ + alert("Failure requesting the contract:\n" + contract_request.statusText); + }; + contract_request.send(null); +} + + +/* This function is called when the user presses the + 'Ok' button. We are now supposed to trigger the + "corret" payment system logic. For this demo, we + only handle "taler". */ +function pay(form) +{ + for (var cnt=0; cnt < form.payment_system.length; cnt++) + { + var choice = form.payment_system[cnt]; + if (choice.checked) + { + if (choice.value == "taler") + { + taler_pay(form); + } + else + { + alert(choice.value + ": NOT available in this demo!"); + } + } + } +}; + + +/* The following event gets fired whenever a customer has a Taler + wallet installed in his browser. In that case, the webmaster can decide + whether or not to display/enable Taler as a payment option in the dialog. */ +function has_taler_wallet_cb(aEvent) +{ + // enable the Taler payment option from the form + var tbutton = document.getElementById("taler-radio-button-id"); + tbutton.removeAttribute("disabled"); + tbutton.setAttribute("checked", "true"); +}; + + +/* Function called when the Taler extension was unloaded; + here we disable the Taler option and check "Lisa", as + some "valid" option should always be selected. */ +function taler_wallet_unload_cb(aEvent) +{ + var tbutton = document.getElementById("taler-radio-button-id"); + tbutton.setAttribute("disabled", "true"); + var lbutton = document.getElementById("lisa-radio-button-id"); + lbutton.setAttribute("checked", "true"); +}; + + +/* The merchant signals its taler-friendlyness to the wallet, + thereby causing the wallet to make itself more visible in the menu. + This function should be called both when the page is loaded + (i.e. via body's onload) and when we receive a "taler-load" signal + (as the extension may be loaded/enabled after the page was loaded) */ +function signal_taler_wallet_onload() +{ + var eve = new Event('taler-probe'); + document.dispatchEvent(eve); +}; + + +// function included to be run to test the page despite a +// wallet not being present in the browser. Enables the +// Taler option. NOT needed in real deployments. +function test_without_wallet(){ + var tbutton = document.getElementById("taler-radio-button-id"); + tbutton.removeAttribute("disabled"); +}; + + +// /////////////// Main logic run first //////////////////////// + +// Register event to be triggered by the wallet as a response to our +// first event +document.addEventListener("taler-wallet-present", + has_taler_wallet_cb, + false); + +// Register event to be triggered by the wallet when it gets enabled while +// the user is on the payment page +document.addEventListener("taler-load", + signal_taler_wallet_onload, + false); + +// Register event to be triggered by the wallet when it is unloaded +document.addEventListener("taler-unload", + taler_wallet_unload_cb, + false); +</script> +</body> +</html> diff --git a/src/frontend_blog/essay_contract.php b/src/frontend_blog/essay_contract.php new file mode 100644 index 00000000..4aeb8c99 --- /dev/null +++ b/src/frontend_blog/essay_contract.php @@ -0,0 +1,78 @@ +<?php +/* + This file is part of GNU TALER. + Copyright (C) 2014, 2015 GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2.1, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along with + TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> +*/ + +/** + * This file should: + * + * 1. check if some article is going to be bought + * 2. check if the wallet is installed TODO + * 3. get the contract (having the teaser as product detail) to the wallet + * + */ +include("../frontend_lib/merchants.php"); +include("./blog_lib.php"); +session_start(); +if (!isset($_SESSION['article'])){ + echo "Please land here just to buy articles"; + die(); + } +$article = $_SESSION['article']; +// 2 to-do + +// send contract +$transaction_id = rand(0, 1001); +$p_id = hexdec(substr(sha1($article), -5)); +$teatax = array ('value' => 1, + 'fraction' => 0, + 'currency' => "KUDOS"); +$now = new DateTime('now'); +$teaser = get_teaser($article); +$pay_url = "essay_pay.php"; +$exec_url = "execute.php"; +$contract_json = generate_contract(1, + 0, + "KUDOS", + $transaction_id, + trim($teaser->nodeValue), + $p_id, + $teatax, + $now, + $pay_url, + $exec_url); +$resp = give_to_backend($_SERVER["HTTP_HOST"], + "backend/contract", + $contract_json); + +// Our response code is the same we got from the backend: +$status_code = $resp->getResponseCode(); +http_response_code ($status_code); + +// Now generate our body +if ($status_code != 200) +{ + echo "Error while generating the contract"; + echo $resp->body->toString (); +} +else +{ $got_json = json_decode ($resp->body->toString ()); + $_SESSION['H_contract'] = $got_json->H_contract; + $_SESSION['article_value'] = 1; + $_SESSION['article_fraction'] = 0; + $_SESSION['article_currency'] = "KUDOS"; + echo $resp->body->toString (); +} +?> diff --git a/src/frontend_blog/essay_fulfillment.php b/src/frontend_blog/essay_fulfillment.php new file mode 100644 index 00000000..df2f8cfa --- /dev/null +++ b/src/frontend_blog/essay_fulfillment.php @@ -0,0 +1,20 @@ +<?php + +session_start(); + +if (!isset($_GET['article'])){ + http_response_code(400); + echo "No article specified"; + die(); +} +$article = $_GET['article']; +/* check if the client is allowed to get the wanted article */ +if(!isset($_SESSION['allowed_articles'][$article])){ + http_response_code(401); // unauthorized + echo "Not allowed to read this article"; + die(); +} +// get the article +$article_doc = get_article($article); +echo $article_doc->saveHTML(); +?> diff --git a/src/frontend_blog/essay_pay.php b/src/frontend_blog/essay_pay.php new file mode 100644 index 00000000..6d906b74 --- /dev/null +++ b/src/frontend_blog/essay_pay.php @@ -0,0 +1,75 @@ +<?php +/* + This file is part of GNU TALER. + Copyright (C) 2014, 2015 GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2.1, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along with + TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> +*/ + +/** + * This file should: + * 1. Check if the session is valid + * 2. augment the deposit permission with missin values + * 3. forward payment to backend + */ + +if (!isset($_SESSION['H_contract'])) +{ + echo "No session active."; + http_response_code (301); + return; +} + +$article = $_SESSION['article']; +$post_body = file_get_contents('php://input'); +$deposit_permission = json_decode ($post_body, true); +$to_add = array('max_fee' => array('value' => 3, + 'fraction' => 8, + 'currency' => $_SESSION['currency']), + 'amount' => array('value' => $_SESSION['article_value'], + 'fraction' => $_SESSION['article_fraction'], + 'currency' => $_SESSION['article_currency'])); +$complete_deposit_permission = array_merge($deposit_permission, $to_add); +$resp = give_to_backend($_SERVER['HTTP_HOST'], + "backend/pay", + $complete_deposit_permission); +$status_code = $resp->getResponseCode(); +// Our response code is the same we got from the backend: +http_response_code ($status_code); + +// Now generate our body +if ($status_code != 200) +{ + /* error: just forwarding to the wallet what + gotten from the backend (which is forwarding 'as is' + the error gotten from the mint) */ + echo json_encode ($new_deposit_permission); + echo "Error came from the backend, payment undone. Status $status_code\n"; + echo "\n"; + echo $resp->body->toString (); +} +else +{ + $_SESSION['payment_ok'] = true; + if (!isset($_SESSION['allowed_articles'])){ + $_SESSION['allowed_articles'] = array ($_SESSION['article'] => true); + else $_SESSION['allowed_articles'] = + array_push($_SESSION['allowed_articles'], array ($article => true)); + } + + http_response_code (301); + $url = (new http\URL($_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'])) + ->mod(array ("path" => "essay_fulfillment.php?article=$article"), http\Url::JOIN_PATH); + header("Location: $url"); + die(); +} + diff --git a/src/frontend_blog/execute.js b/src/frontend_blog/execute.js new file mode 100644 index 00000000..a9045cb5 --- /dev/null +++ b/src/frontend_blog/execute.js @@ -0,0 +1,33 @@ +"use strict"; +// JSX literals are compiled to calls to React.createElement calls. +let React = { + createElement: function (tag, props, ...children) { + let e = document.createElement(tag); + for (let k in props) { + e.setAttribute(k, props[k]); + } + for (let child of children) { + if ("string" === typeof child || "number" == typeof child) { + child = document.createTextNode(child); + } + e.appendChild(child); + } + return e; + } +}; +document.addEventListener("DOMContentLoaded", function (e) { + var eve = new CustomEvent('taler-execute-payment', { detail: { H_contract: h_contract } }); + document.dispatchEvent(eve); +}); +function replace(el, r) { + el.parentNode.replaceChild(r, el); +} +document.addEventListener("taler-payment-result", function (e) { + if (!e.detail.success) { + alert("Payment failed\n" + JSON.stringify(e.detail)); + return; + } + console.log("finished payment"); + let msg = React.createElement("div", null, "Payment successful. View your ", React.createElement("a", {"href": e.detail.fulfillmentUrl}, "product"), "."); + replace(document.getElementById("loading"), msg); +}); diff --git a/src/frontend_blog/execute.php b/src/frontend_blog/execute.php new file mode 100644 index 00000000..33021fd3 --- /dev/null +++ b/src/frontend_blog/execute.php @@ -0,0 +1,56 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <title>Toy Store - Taler Demo</title> + <link rel="stylesheet" type="text/css" href="style.css"> + <script> /* @licstart The following is the entire license notice for the + JavaScript code in this page. + + Copyright (C) 2015 GNUnet e.V. + + The JavaScript code in this page is free software: you can + redistribute it and/or modify it under the terms of the GNU + Lesser General Public License (GNU LGPL) as published by the Free Software + Foundation, either version 2.1 of the License, or (at your option) + any later version. The code is distributed WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU LGPL for more details. + + As additional permission under GNU LGPL version 2.1 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU LGPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + @licend The above is the entire license notice + for the JavaScript code in this page. + */ + </script> + <script type="text/javascript"> +<?php +session_start(); +echo "var h_contract=\"$_SESSION[H_contract]\";\n"; +?> + </script> + <script type="text/javascript" src="execute.js"></script> +</head> + +<body> + <header> + <div id="logo"> + <svg height="100" width="100"> + <circle cx="50" cy="50" r="40" stroke="darkcyan" stroke-width="6" fill="white" /> + <text x="19" y="82" font-family="Verdana" font-size="90" fill="darkcyan">S</text> + </svg> + </div> + <h1>Toy Store - Taler Demo</h1> + </header> + + <aside class="sidebar" id="left"> + </aside> + + <section id="main"> + <h1>Executing Payment ...</h1> + <div id="loading">Loading...</div> +</body> +</html> diff --git a/src/frontend_blog/execute.tsx b/src/frontend_blog/execute.tsx new file mode 100644 index 00000000..67cf8e06 --- /dev/null +++ b/src/frontend_blog/execute.tsx @@ -0,0 +1,41 @@ +"use strict"; + + +// JSX literals are compiled to calls to React.createElement calls. +let React = { + createElement: function(tag, props, ...children) { + let e = document.createElement(tag); + for (let k in props) { + e.setAttribute(k, props[k]); + } + for (let child of children) { + if ("string" === typeof child || "number" == typeof child) { + child = document.createTextNode(child); + } + e.appendChild(child); + } + return e; + } +}; + +declare var h_contract: string; + +document.addEventListener("DOMContentLoaded", function (e) { + var eve = new CustomEvent('taler-execute-payment', {detail: {H_contract: h_contract}}); + document.dispatchEvent(eve); +}); + +function replace(el, r) { + el.parentNode.replaceChild(r, el); +} + +document.addEventListener("taler-payment-result", function (e: CustomEvent) { + if (!e.detail.success) { + alert("Payment failed\n" + JSON.stringify(e.detail)); + return; + } + console.log("finished payment"); + let msg = + <div>Payment successful. View your <a href={e.detail.fulfillmentUrl}>product</a>.</div>; + replace(document.getElementById("loading"), msg); +}); diff --git a/src/frontend_blog/index.html b/src/frontend_blog/index.html new file mode 100644 index 00000000..a1ad1db7 --- /dev/null +++ b/src/frontend_blog/index.html @@ -0,0 +1,79 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <title>Blog site demonstration</title> + <link rel="stylesheet" type="text/css" href="style.css"> + <script type="text/javascript"> + /* @licstart The following is the entire license notice for the + JavaScript code in this page. + + Copyright (C) 2015 GNUnet e.V. + + The JavaScript code in this page is free software: you can + redistribute it and/or modify it under the terms of the GNU + Lesser General Public License (GNU LGPL) as published by the Free Software + Foundation, either version 2.1 of the License, or (at your option) + any later version. The code is distributed WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU LGPL for more details. + + As additional permission under GNU LGPL version 2.1 section 7, you + may distribute non-source (e.g., minimized or compacted) forms of + that code without the copy of the GNU LGPL normally required by + section 4, provided you include this license notice and a URL + through which recipients can access the Corresponding Source. + + @licend The above is the entire license notice + for the JavaScript code in this page. + */ + </script> +</head> + +<body> + <header> + <div id="logo"> + <svg height="100" width="100"> + <circle cx="50" cy="50" r="40" stroke="darkcyan" stroke-width="6" fill="white" /> + <text x="19" y="82" font-family="Verdana" font-size="90" fill="darkcyan">B</text> + </svg> + </div> + + <h1>Blog site demonstration</h1> + </header> + + <aside class="sidebar" id="left"> + </aside> + + <section id="main"> + <article> + <h1>Welcome to the Taler blog</h1> + <p>This blog simulates how a website selling articles which integrates + Taler should work. If you don't have a Taler wallet installed, + please visit <a href="https://demo.taler.net">demo.taler.net</a>. + By clicking on some article below, you get its teaser shown, but the + actual purchase happens once you will click on the 'read more' link + associated with that teaser. + </p> + </article> + <section> + + <article> + <h2>Articles list</h2> + </article> + + <article class="articles"> + <ul style="list-style-type:none"> + <li> + <a href="/teaser.php?article=essay-x"> + <div class="teasers_item"> + <h3>Essay x</h3> + <p>In essay x, we will ...</p> + </div> + </a> + </li> + </ul> + </article> + </section> + </section> +</body> +</html> diff --git a/src/frontend_blog/style.css b/src/frontend_blog/style.css new file mode 100644 index 00000000..c2cc51ee --- /dev/null +++ b/src/frontend_blog/style.css @@ -0,0 +1,123 @@ +body { + background-color: white; + margin: 0; + padding: 0; + font-family: Verdana, sans; +} + +header { + width: 100%; + height: 100px; + margin: 0; + padding: 0; + border-bottom: 1px solid black; +} + +header h1 { + font-size: 200%; + margin: 0; + padding: 0 0 0 120px; + position: relative; + top: 50%; + transform: translateY(-50%); +} + +header #logo { + float: left; + width: 100px; + padding: 0; + margin: 0; + text-align: center; + border-right: 1px solid black; +} + +aside { + width: 100px; + float: left; +} + +section#main { + margin: 0 0 0 100px; + padding: 20px; + border-left: 1px solid black; + height: 100%; + max-width: 40em; +} + +section#main h1:first-child { + margin-top: 0; +} + +h1 { + font-size: 160%; +} + +h2 { + font-size: 140%; +} + +h3 { + font-size: 120%; +} + +h4, h5, h6 { + font-size: 100%; +} + +.loader { + font-size: 10px; + margin: 50px auto; + text-indent: -9999em; + width: 11em; + height: 11em; + border-radius: 50%; + background: #ffffff; + background: -moz-linear-gradient(left, #000 10%, rgba(255, 255, 255, 0) 42%); + background: -webkit-linear-gradient(left, #000 10%, rgba(255, 255, 255, 0) 42%); + background: -o-linear-gradient(left, #000 10%, rgba(255, 255, 255, 0) 42%); + background: -ms-linear-gradient(left, #000 10%, rgba(255, 255, 255, 0) 42%); + position: relative; + -webkit-animation: load3 1.4s infinite linear; + animation: load3 1.4s infinite linear; + -webkit-transform: translateZ(0); + -ms-transform: translateZ(0); + transform: translateZ(0); +} + +.loader:after { + background: #fff; + width: 75%; + height: 75%; + border-radius: 50%; + content: ''; + margin: auto; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; +} + +@-webkit-keyframes load3 { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + +@keyframes load3 { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} + + diff --git a/src/frontend_blog/teaser.php b/src/frontend_blog/teaser.php new file mode 100644 index 00000000..e5f2e97b --- /dev/null +++ b/src/frontend_blog/teaser.php @@ -0,0 +1,46 @@ +<html> +<?php +/* + This file is part of GNU TALER. + Copyright (C) 2014, 2015 GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 2.1, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along with + TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> +*/ + +/** + * This file should: + * + * 1. fetch the article teaser and attach a 'read more' link to it + * + */ +$article = (isset($_GET['article']) ? $_GET['article'] : "No article"); +$content = file_get_contents("articles/$article.html"); +$doc = new DOMDocument(); +$doc->loadHTML($content); +$teaser = $doc->getElementById("teaser"); +?> +<head> + <title> + <?php echo $article ?> + </title> +</head> +<body> +<?php if ($article == "No article") + echo "Please select some article"; + else { + session_start(); + $_SESSION['article'] = $article; + echo $teaser->nodeValue + . "<br><a href=\"/essay_checkout.php\">read more</a>";}; ?> + +<body> +</html> diff --git a/src/frontend_lib/merchants.php b/src/frontend_lib/merchants.php new file mode 100644 index 00000000..bbb0d90e --- /dev/null +++ b/src/frontend_lib/merchants.php @@ -0,0 +1,91 @@ +<?php +/** + * Return a contract proposition to forward to the backend + * Note that `teatax` is an associative array representing a + * Taler-style amount (so it has the usual <amount,fration,currency> + * triple). Moreover, `teatax` should be a *list* of taxes + */ +function generate_contract($amount_value, + $amount_fraction, + $currency, + $transaction_id, + $desc, + $p_id, + $teatax, + $now, + $pay_url, + $exec_url){ + $contract = array ('amount' => array ('value' => $amount_value, + 'fraction' => $amount_fraction, + 'currency' => $currency), + 'max_fee' => array ('value' => 3, + 'fraction' => 01010, + 'currency' => $currency), + 'transaction_id' => $transaction_id, + 'products' => array ( + array ('description' => $desc, + 'quantity' => 1, + 'price' => array ('value' => $amount_value, + 'fraction' => $amount_fraction, + 'currency' => $currency), + 'product_id' => $p_id, + 'taxes' => array (array ('teatax' => $teatax)), + 'delivery_date' => "Some Date Format", + 'delivery_location' => 'LNAME1')), + 'timestamp' => "/Date(" . $now->getTimestamp() . ")/", + 'pay_url' => $pay_url, + 'exec_url' => $exec_url, + 'expiry' => "/Date(" . $now->add(new DateInterval('P2W'))->getTimestamp() . ")/", + 'refund_deadline' => "/Date(" . $now->add(new DateInterval('P3M'))->getTimestamp() . ")/", + 'merchant' => array ('address' => 'LNAME2', + 'name' => 'test merchant', + 'jurisdiction' => 'LNAME3'), + + 'locations' => array ('LNAME1' => array ('country' => 'Test Country', + 'city' => 'Test City', + 'state' => 'Test State', + 'region' => 'Test Region', + 'province' => 'Test Province', + 'ZIP code' => 4908, + 'street' => 'test street', + 'street number' => 20), + 'LNAME2' => array ('country' => 'Test Country', + 'city' => 'Test City', + 'state' => 'Test State', + 'region' => 'Test Region', + 'province' => 'Test Province', + 'ZIP code' => 4908, + 'street' => 'test street', + 'street number' => 20), + 'LNAME3' => array ('country' => 'Test Country', + 'city' => 'Test City', + 'state' => 'Test State', + 'region' => 'Test Region', + 'province' => 'Test Province', + 'ZIP code' => 4908))); + $json = json_encode (array ('contract' => $contract, 'exec_url' => $exec_url, 'pay_url' => $pay_url), JSON_PRETTY_PRINT); + return $json; +} + + + +/** + * Feed `$json` to the backend and return the "(pecl) http response object" + * corresponding to the `$backend_relative_url` call + */ +function give_to_backend($backend_host, $backend_relative_url, $json){ + $url = (new http\URL("http://$backend_host")) + ->mod(array ("path" => $backend_relative_url), http\Url::JOIN_PATH); + + $req = new http\Client\Request("POST", + $url, + array ("Content-Type" => "application/json")); + + $req->getBody()->append($json); + + // Execute the HTTP request + $client = new http\Client; + $client->enqueue($req)->send(); + return $client->getResponse(); +} +?> |