Cartkit & Uniform payment system

Hi
I have a project to build a payment system by check and paypal. I’m using Cartkit and Uniform plugin (both amasing btw). With Cartkit, the user can choose product, refresh the cart, and pay by PAYPAL. With Uniform, it could be possible to pay by CHECK, sending by mail the products and customer information, delivery adress, etc.

Separately, both plugin are working very well. But now, I’m trying to include uniform to the cart.php from Cartkit. And here is the issue, I get an error saying The CSRF token was invalid.

I send here a reduced code of the cart.php, after copying the uniform into the cart.

<?php $cart = cart_logic(get_cart()) ?>
<?php $products = $pages->find('bookstore')->children()->visible() ?>
<?php snippet('header') ?>

<?php if(count($cart) == 0): ?>

<main id="cart" class="main black" role="main">
   <?php if($page->sandbox() != 'true'): ?>
   <form method="post" action="https://www.sandbox.paypal.com/cgi-bin/webscr">
      <?php else: ?>
      <form method="post" action="https://www.paypal.com/cgi-bin/webscr">
         <?php endif ?>

        //  MY CODE WHEN THE CART IS EMPTY

      </form>

      </main>

   <?php else: ?>

        //  MY CODE WHEN THE CART IS FULL

   <main id="cart" class="main" role="main">


      <?php if($page->sandbox() != 'true'): ?>
      <form method="post" action="https://www.sandbox.paypal.com/cgi-bin/webscr">
         <?php else: ?>
         <form method="post" action="https://www.paypal.com/cgi-bin/webscr">
            <?php endif ?>
            <input type="hidden" name="cmd" value="_cart">
            <input type="hidden" name="upload" value="1">
            <input type="hidden" name="business" value="<?php echo $site->email() ?>">
            <input type="hidden" name="currency_code" value="<?php echo $site->currency_code() ?>">
            <input type="hidden" name="cbt" value="Return to <?php echo $site->title() ?>">
            <input type="hidden" name="cancel_return" value="<?php echo url('cart') ?>">
            <input type="hidden" name="return" value="<?php echo url('cart/paid') ?>">
            <table cellpadding="6" rules="GROUPS" frame="BOX">
               <thead>
                  <tr>
                     <th><?php echo $site->produit()->html() ?></th>
                     <th></th>
                     <th><?php echo $site->quantite()->html() ?></th>
                     <th></th>
                     <th></th>
                     <th></th>
                     <th></th>
                     <th><?php echo $site->price()->html() ?></th>
                  </tr>
               </thead>
               <tbody>
                  <?php $i=0; $count = 0; $total = 0; ?>
                  <?php foreach($cart as $id => $quantity): ?>
                  <?php if($product = $products->findByURI($id)): ?>
                  <?php $i++; ?>
                  <?php $count += $quantity ?>
                  <tr>
                     <td class="image">
                        <div>
                           <input type="hidden" name="item_name_<?php echo $i ?>" value="<?php echo $product->title() ?>" />
                           <input type="hidden" name="amount_<?php echo $i ?>" value="<?php echo $product->price() ?>" />
                           <a href="<?php echo $product->url() ?>">

                              <?php if($image = $product->images()->sortBy('sort', 'asc')->first()): ?>
                              <?php echo thumb($image, array('width' => 640, 'height' => 412, 'crop' => true, 'quality' => 100)); ?>
                              <?php endif ?>
                           </a>
                        </div>
                     </td>
                     <td  class="product">

                        <dl>
                           <dt><span><?php echo $site->titreprojet()->html() ?></span><span><?php echo $product->title()->html() ?></span></dt>
                           <dt><span><?php echo $site->auteur()->html() ?></span><span><?php echo $product->auteur()->html() ?></span></dt>
                           <dt><span><?php echo $site->langue()->html() ?></span><span><?php echo $product->langue()->html() ?></span></dt>
                           <dt><span><?php echo $site->format()->html() ?></span><span><?php echo $product->format()->html() ?></span></dt>
                           <dt><span><?php echo $site->pagination()->html() ?></span><span><?php echo $product->pages()->html() ?></span></dt>
                           <dt><span><?php echo $site->technique()->html() ?></span><span><?php echo $product->technique()->html() ?></span></dt>
                           <dt><span><?php echo $site->tirage()->html() ?></span><span><?php echo $product->tirage()->html() ?></span></dt>
<dt><span>ISBN</span><span><?php echo $product->isbn()->html() ?></span></dt>
                        </dl>

                     </td>

                     <td >
                        <input data-id="<?php echo $product->uid() ?>" data-quantity="<?php echo $quantity ?>" pattern="[0-9]*" class="quantity" type="hidden" name="quantity_<?php echo $i ?>" min="1" value="<?php echo $quantity ?>">
                        <?php echo $quantity ?>
                     </td>
                     <td class="add">
                        <a class="btn" href="<?php echo url('cart') ?>?action=add&amp;id=<?php echo $product->uid() ?>">+</a>

                     </td>
                     <td class="sous">

                        <?php if ($quantity > 1): ?>
                        <a class="btn" href="<?php echo url('cart') ?>?action=remove&amp;id=<?php echo $product->uid() ?>">-</a>
                        <?php endif ?>
                        <?php $prodtotal = floatval($product->price()->value)*$quantity ?>
                     </td>
                     <td></td>
                     <td class="retirer"><a class="btn" href="<?php echo url('cart') ?>?action=delete&amp;id=<?php echo $product->uid() ?>"><?php echo $site->retirer()->html() ?></a></td>
                     <td><?php printf('%0.2f', $prodtotal) ?>&#8239;<?php echo $site->currency_symbol() ?></td>
                  </tr>
                  <?php $total += $prodtotal ?>
                  <?php endif; ?>
                  <?php endforeach; ?>
               </tbody>
               <tfoot>
                  <tr>
                     <td class="empty"></td>
                     <td class="margin"><?php echo $site->soustotal()->html() ?></td>
                     <td class="empty"></td>
                     <td class="empty"></td>
                     <td class="empty"></td>

                     <td class="empty"></td>
                     <td class="empty"></td>
                     <td><?php printf('%0.2f', $total) ?>&#8239;<?php echo $site->currency_symbol() ?></td>

                  </tr>
                  <tr>
                     <?php $postage = cart_postage($total) ?>
                     <td></td>
                     <td  class="margin"><?php echo $site->fraisdeport()->html() ?></td>
                     <td class="empty"></td>

                     <input type="hidden" name="shipping_<?php echo $i ?>" value="<?php printf('%0.2f', $postage) ?>" />
                     <td class="empty"></td>
                     <td class="empty"></td>
                     <td class="empty"></td>
                     <td class="empty"></td>
                     <td><?php printf('%0.2f', $postage) ?>&#8239;<?php echo $site->currency_symbol() ?></td>
                  </tr>
                  <tr>
                     <th class="empty"></th>
                     <th  class="margin"><?php echo $site->montanttotal()->html() ?></th>
                     <th></th>

                     <td class="empty"></td>
                     <td class="empty"></td>
                     <th class="empty"></th>
                     <th class="empty"></th>
                     <th><?php printf('%0.2f', $total+$postage) ?>&#8239;<?php echo $site->currency_symbol() ?></th>
                  </tr>
                  <tr>
                     <th><div class="submit">
                        <div>Etape 1/3</div></div>
                     </th>
                     <th  colspan="8"><a class="btn" href="<?php echo page('forumulaire')->url() ?>">Paser à l'étape 3</a></th>
                  </tr>
               </tfoot>
            </table>

         </form>

         <section class="text">


           // THE UNIFORM HERE

            <div class="head">
               <span><?php echo l::get('infocli') ?></span><span><?php echo l::get('adressefac') ?></span><span><?php echo l::get('adresseliv') ?></span>
            </div>
            <form action="<?php echo $page->url() ?>" method="POST">
               <div>
                  <span><?php echo l::get('email') ?></span><input name="email_cli" placeholder="..." type="email" value="<?php echo $form->old('email_cli'); ?>">
                  <span><?php echo l::get('civilite') ?></span>
                  <div>

                     <?php $value = $form->old('civilite_cli') ?>
                     <label>
                        <!-- Set this as default -->
                        <input type="radio" name="civilite_cli" value="Mme"<?php e($value=='mme', ' checked')?>/> Mme
                     </label>
                     <label>
                        <input type="radio" name="civilite_cli" value="M"<?php e($value=='m', ' checked')?>/> M
                     </label>

                  </div>
                  <span><?php echo l::get('prenom') ?></span><input class="prenom civ" name="prenom_cli" placeholder="..." value="<?php echo $form->old('prenom_cli'); ?>">
                  <span><?php echo l::get('nom') ?></span><input class="nomun border" name="nom_cli" placeholder="..." value="<?php echo $form->old('nom_cli'); ?>">
               </div>


               <?php echo csrf_field(); ?>
               <?php echo honeypot_field(); ?>
               <div class="submit">
                  <div>Etape 2/3</div>
                  <input type="submit" value="Passer à l'étape 3">
               </div>
            </form>


            <?php if ($form->success()): ?>
            <div class="uniform-errors"><?php echo l::get('msgsuccess') ?></div>
            <?php else: ?>
            <?php snippet('uniform/errors', ['form' => $form]); ?>
            <?php endif; ?>

         </section>

         </main>

      <?php endif; ?>

      <?php snippet('footer') ?>

And the controller from uniform is quite simple (controllers/cart.php)

<?php

use Uniform\Form;

return function ($site, $pages, $page)
{
    $form = new Form([
        'email_cli' => [
            'rules' => ['required', 'email'],
            'message' => "Vous n'avez pas rentrer d'email (Informations client)",
        ],
        'prenom_cli' => [
            'rules' => ['required'],
            'message' => "Vous n'avez pas rentrer de  prénom (Informations client)",
        ],
      'civilite_cli' => [
            'rules' => ['required' => [['mme', 'm']]],
            'message' => "Vous n'avez pas rentrer de  civilité (Informations client)",
        ],
        'nom_cli' => [
            'rules' => ['required'],
            'message' => "Vous n'avez pas rentrer de  nom (Informations client)",
        ],
    ]);

    if (r::is('POST')) {
        $form->emailAction([
            'to' => 'mymail@gmail.com',
            'from' => 'mailer@press.org',
            'service' => 'html-mail',
            'subject' => 'Nouvelle commande  ',
            'snippet' => 'emails/email',
        ])
           ->emailAction([
                'to' => $form->data('email_cli'),
                'from' => 'mailer@press.org',
                'service' => 'html-mail',
                'replyTo' => 'mymail@gmail.com',
                'subject' => 'Merci pour votre commande',
                'snippet' => 'emails/success',
            ]);
    }

    return compact('form');
};

Does Uniform work if you replace $cart = cart_logic(get_cart()) with $cart = []? Maybe Cartkit does something to the session that removes the CSRF token.

Thanks for your reply. Unfortunately, I get the same error message with CSRF.
My goal is pretty simple but ambitious too : improve Cartkit to let user pay by check, not only by paypal.

The plugin seems pretty simple too, but I don’t understand the logic.

/plugins/cart/cart.php

<?php
function get_cart() {
    s::start();
    $cart = s::get('cart', array());
    return $cart;
}

function cart_logic($cart) {

    if (isset($_REQUEST['action'])) {
      $action = $_REQUEST['action'];
      $id = $_REQUEST['id'];
      switch ($action) {
          case 'add':
              if (isset($cart[$id])) {
                  $cart[$id]++;
              } else {
                  $cart[$id] = 1;
              }
              break;
          case 'remove':
              if (isset($cart[$id])) {
                  $cart[$id]--;
              } else {
                  $cart[$id] = 1;
              }
              break;
          case 'update':
              if (isset($_REQUEST['quantity'])) {
                  $quantity = intval($_REQUEST['quantity']);
                  if ($quantity < 1) {
                      unset($cart[$id]);
                  } else {
                      $cart[$id] = $quantity;                
                  }
              }
              break;
          case 'delete':
              if (isset($cart[$id])) {
                  unset($cart[$id]);
              }
              break;
      }
      s::set('cart', $cart);
    }
    
//    if (count($cart) == 0) {
//    	go(url('products'));        
//    }
    
    return $cart;
}

function cart_count($cart) {
    $count = 0;
    foreach ($cart as $id => $quantity) {
        $count += $quantity;
    }
    return $count;
}

function cart_postage($total) {
    $postage;
    switch ($total) {
        case ($total < 10):
            $postage = 2.5;
            break;
        case ($total < 30):
            $postage = 5.5;
            break;
        case ($total < 75):
            $postage = 8;
            break;
        case ($total < 150):
            $postage = 11.56;
            break;
        case ($total < 300):
            $postage = 28.30;
            break;
        default:
            $postage = 40.75;
    }
    return $postage;
}

Remove or comment out everything in your template, except for the Uniform form. Then see if it works. If it does, add the other lines step by step and see when it breaks again.

Yes,

  • if I remove everything from cart.php except the uniform, I can see the form (when the cart is empty)
  • if I click on “add product”, it redirect on cart.php but with CSRF error. (I expected a Carkit error because the cart script is removed, there is only the form).
  • There is four functions in plugin/cart.php : get_cart, cart_logic, cart_count, cart_postage. If I remove each one of them, the product pages breaks except for cart_logic. But if I remove cart_logic, when adding a product, I get the CSRF error (and I expected a Carkit error too because the cart.php only display the uniform).

If you don’t know Cartkit, we are automatically redirect to the cart.php template iif we click on “add a product” from the product page. It seems like everything goes wrong when adding something to the cart with uniform inside.

The “add product” script looks like that :

<form method="post" action="<?php echo url('cart') ?>">
    <input type="hidden" name="action" value="add">
    <input type="hidden" name="id" value="<?php echo $page->uid() ?>">
    <button class="btn" type="submit">Add product</button>
</form> 

In fact, Cartkit is an upgrade to an old tutorial for Kirby <2. You can find it here https://getkirby.com/forum/archive/how-to/20130402/paypal-ecommerce-store.

Some of the comments I could see here and there already asked to have another payement system instead of paypal. I think a form to pay by check, keeping every informations inside the cart with Uniform, could be very helpful.

I continue to program my form system with Cartkit. I started again from zero : installed Cartkit and Uniform only.
I appears that the form from Cartkit to send the data to the cart was written like that :

 <form method="post" action="<?php echo url('cart') ?>">
  ....
</form> 

And that interfere with the uniform r::is('POST') controllers from

if (r::is('POST')) {
        $form->emailAction([
            'to' => 'me@example.com',
            'from' => 'info@example.com',
        ]);
    }

So…I changed the method="post" action by method="get", and it seems to work now :wink: I can continue my project now, but I have to be carefull with other issues and I hope this is a good solution, this sound a little tricky.

The main consequence with GET, is to rewrite the URL like that : site.com/cart?action=add&id=time-travel

I see, but you shouldn’t use different HTTP verbs (POST, GET) just to keep requests of different forms separated. Use the value of a hidden form field instead.

  1. Add this to the Uniform form:
    <input type="hidden" name="payment_method" value="check">
    
  2. Update the controller
    if (r::is('POST') && get('payment_method') === 'check') {
       $form->emailAction(...
    
1 Like

This is working very good thanks

Hello

Always working on my payment system with uniform, I have to send some arrays and I don’t know how to do it.
These arrays are in a foreach loop, so I can have multiple entries. This is what I want to send :

            <?php $i=0; $count = 0; $total = 0; ?>
            <?php foreach($cart as $id => $quantity): ?>
            <?php if($product = $products->findByURI($id)): ?>
            <?php $i++; ?>
            <?php $count += $quantity ?>

                 <span><?php echo $product->title()->html() ?></span>
                 <span><?php echo $quantity ?></span>
                 <span><?php printf('%0.2f', $prodtotal) ?>&#8239;<?php echo $site->currency_symbol() ?></span>
            
            <?php endif; ?>
            <?php endforeach; ?>

The question is how to send simple data independently of a value written by the user.

I’m afraid I don’t quite understand your question. Do you have the $cart array and want to send this as formatted HTML email when a form is submitted?

Yes, this is exactly what I would like to do. I didn’t find any documentation on this.

You can use the email action with the snippet option:

$form->emailAction([
   'to' => 'me@example.com',
   'from' => 'info@example.com',
   'snippet' => 'order',
   'cart' => $cart,
]);

This uses a site/snippets/order.php snippet to create the email. Inside the snippet you have access to the form $data and to $options['cart'].

To send an HTML email you need a custom email service like this one or use a package like Phpmailer.

I don’t know why I’m getting an empty value inside the mail.
I displayed the 'cart' => $cart inside the controller, I already have configured the html-mail service, and I tried $data['cart'] and $options['cart'] inside the snippet, but both not working.

My $cart array is between the <form action="<?php echo $page->url() ?>" method="POST"> and </form>

Your answer looked pretty simple but I don’t know why it doesn’t work. Any suggestions ?


I tried with a very simple array I receive the mail, but the array doesn’t appear.

            <?php $hello = date('d/m/Y');  
            echo $hello
            ?>

controller

$form->emailAction([
         'to' => 'mymail@yahoo.fr',
         'from' => 'othermail@press.org',
         'service' => 'html-mail',
         'subject' => 'Hello you ',
         'snippet' => 'emails/email',
         'hello' => $hello,
      ])

email.php

         <tr>
            <th><?php echo $options['hello'] ?></th>
            <th><?php echo $data['hello'] ?></th>
            <th></th>
            <th></th>
         </tr>

Okay, this means I haven’t understood your question after all :smile: Please show me your complete controller, template and email snippet.

I think you really understood. Quite embarassing, I can’t explain more simply as : “how to send an array with uniform”…
You might be afraid by the length of the files, but here they are

The template

<?php $cart = cart_logic(get_cart()) ?>
<?php $products = $pages->find('bookstore')->children()->visible() ?>
<?php snippet('header') ?>

<?php if(count($cart) == 0): ?>

<main id="cart" class="main">

   <?php /*----- NO PRODUCT -----*/ ?>

   <section>
      <div class="prod_head">
         <div><?php echo $site->produit()->html() ?></div>
         <div><?php echo $site->quantite()->html() ?></div>
         <div><?php echo $site->price()->html() ?></div>
      </div>

      <div class="prod_table">
         <div class="image">
            <img src="assets/images/fond.gif">
         </div>
         <div class="product">
            <dl>
               <dt class="titre"><span ><?php echo $site->titreprojet()->html() ?></span><span>-</span></dt>
               <dt><span><?php echo $site->auteur()->html() ?></span><span>-</span></dt>
               <dt><span><?php echo $site->langue()->html() ?></span><span>-</span></dt>
               <dt><span><?php echo $site->format()->html() ?></span><span>-</span></dt>
               <dt><span><?php echo $site->pagination()->html() ?></span><span>-</span></dt>
               <dt><span><?php echo $site->technique()->html() ?></span><span>-</span></dt>
               <dt><span><?php echo $site->tirage()->html() ?></span><span>-</span></dt>
               <dt><span>ISBN</span><span>-</span></dt>
            </dl>
         </div>
         <div class="quantity">- </div>
         <div class="add"><a class="btn disable" href="">+</a></div>
         <div class="sous"><a class="btn disable" href="">-</a></div>
         <div class="empty"></div>
         <div class="retirer"><a class="btn" href=""><?php echo $site->retirer()->html() ?></a></div>
         <div class="total">-</div>
      </div>

      <div class="prod_sstotal">
         <div></div>
         <div><span></span><span><?php echo $site->soustotal()->html() ?></span></div>
         <div></div>
         <div>-</div>
      </div>

      <div class="empty"></div>

      <?php /*----- NO PRODUCT -----*/ ?>
   </section>


</main>

<?php else: ?>

<main id="cart" class="main" role="main">



   <form method="post" action="https://www.paypal.com/cgi-bin/webscr">

      <input type="hidden" name="cmd" value="_cart">
      <input type="hidden" name="upload" value="1">
      <input type="hidden" name="business" value="<?php echo $site->email() ?>">
      <input type="hidden" name="currency_code" value="<?php echo $site->currency_code() ?>">
      <input type="hidden" name="cbt" value="Return to <?php echo $site->title() ?>">
      <input type="hidden" name="cancel_return" value="<?php echo url('cart') ?>">
      <input type="hidden" name="return" value="<?php echo url('cart/paid') ?>">

      <section>
         <div class="prod_head">
            <div><?php echo $site->produit()->html() ?></div>
            <div><?php echo $site->quantite()->html() ?></div>
            <div><?php echo $site->price()->html() ?></div>
         </div>
         <?php $i=0; $count = 0; $total = 0; ?>
         <?php foreach($cart as $id => $quantity): ?>
         <?php if($product = $products->findByURI($id)): ?>
         <?php $i++; ?>
         <?php $count += $quantity ?>

         <div class="prod_table">

            <div class="image">
               <input type="hidden" name="item_name_<?php echo $i ?>" value="<?php echo $product->title() ?>" />
               <input type="hidden" name="amount_<?php echo $i ?>" value="<?php echo $product->price() ?>" />
               <a href="<?php echo $product->url() ?>">
                  <?php if($image = $product->images()->sortBy('sort', 'asc')->first()): ?>
                  <?php echo thumb($image, array('width' => 640, 'height' => 412, 'crop' => true, 'quality' => 100)); ?>
                  <?php endif ?>
               </a>
            </div>

            <div class="product">
               <dl>
                  <dt class="titre"><span ><?php echo $site->titreprojet()->html() ?></span><span><?php echo $product->title()->html() ?></span></dt>
                  <dt><span><?php echo $site->auteur()->html() ?></span><span><?php echo $product->auteur()->html() ?></span></dt>
                  <dt><span><?php echo $site->langue()->html() ?></span><span><?php echo $product->langue()->html() ?></span></dt>
                  <dt><span><?php echo $site->format()->html() ?></span><span><?php echo $product->format()->html() ?></span></dt>
                  <dt><span><?php echo $site->pagination()->html() ?></span><span><?php echo $product->pages()->html() ?></span></dt>
                  <dt><span><?php echo $site->technique()->html() ?></span><span><?php echo $product->technique()->html() ?></span></dt>
                  <dt><span><?php echo $site->tirage()->html() ?></span><span><?php echo $product->tirage()->html() ?></span></dt>
                  <dt><span>ISBN</span><span><?php echo $product->isbn()->html() ?></span></dt>
               </dl>
            </div>

            <div class="quantity">
               <input data-id="<?php echo $product->uid() ?>" data-quantity="<?php echo $quantity ?>" pattern="[0-9]*" class="quantity" type="hidden" name="quantity_<?php echo $i ?>" min="1" value="<?php echo $quantity ?>">
               <?php echo $quantity ?>
            </div>
            <div class="add">
               <a class="btn" href="<?php echo url('cart') ?>?action=add&amp;id=<?php echo $product->uid() ?>">+</a>

            </div>
            <div class="sous">
               <?php if ($quantity > 1): ?>
               <a class="btn" href="<?php echo url('cart') ?>?action=remove&amp;id=<?php echo $product->uid() ?>">-</a>
               <?php else: ?>
               <div class="btn disable">-</div>
               <?php endif ?>
               <?php $prodtotal = floatval($product->price()->value)*$quantity ?>
            </div>
            <div class="empty">

            </div>
            <div class="retirer">
               <a class="btn" href="<?php echo url('cart') ?>?action=delete&amp;id=<?php echo $product->uid() ?>"><?php echo $site->retirer()->html() ?></a>
            </div>
            <div class="total">
               <?php printf('%0.2f', $prodtotal) ?>&#8239;<?php echo $site->currency_symbol() ?>
            </div>
         </div>
         <?php $total += $prodtotal ?>
         <?php endif; ?>
         <?php endforeach; ?>

         <div class="prod_sstotal">
            <div></div>
            <div><span></span><span><?php echo $site->soustotal()->html() ?></span></div>
            <div></div>
            <div><?php printf('%0.2f', $total) ?>&#8239;<?php echo $site->currency_symbol() ?></div>
         </div>

         <div class="empty">
         </div>

         <div class="prod_monde">
            <label><input type="radio" id='watch-me' data-price="67" name="" value="Mme"/>France</label>
            <label><input type="radio" id='watch-me' data-price="37" name="civilite_cli" value="M"/>Europe</label>
            <label><input type="radio" id='watch-me' data-price="27" name="civilite_cli" value="M"/>Monde</label>
         </div>

         <?php $postage = cart_postage($total) ?>
         <div class="prod_fraisport">
            <input type="hidden" name="shipping_<?php echo $i ?>" value="<?php printf('%0.2f', $postage) ?>" />
            <div></div>
            <div><span></span><span><?php echo $site->fraisdeport()->html() ?></span></div>
            <div></div>
            <div class="calc_frais"><?php printf('%0.2f', $postage) ?>&#8239;<?php echo $site->currency_symbol() ?></div>
         </div>



         <div class="prod_total">
            <div></div>
            <div><span></span><span><?php echo $site->montanttotal()->html() ?></span></div>
            <div></div>
            <div><?php printf('%0.2f', $total+$postage) ?>&#8239;<?php echo $site->currency_symbol() ?></div>
         </div>

         <div class="prod_pay">
            <div class="btn cheque" >Payer par chèque</div>
            <input class="btn" type="submit" value="Payer par Paypal">
         </div>


      </section>
   </form>
   <section class="form">

      <?php /*----- FORM -----*/ ?>
      
      <form action="<?php echo $page->url() ?>#cheque" method="POST">
         <div class="producthide">
            
            <?php $i=0; $count = 0; $total = 0; ?>
            <?php foreach($cart as $id => $quantity): ?>
            <?php if($product = $products->findByURI($id)): ?>
            <?php $i++; ?>
            <?php $count += $quantity ?>
            <span><?php echo $product->title()->html() ?>, <?php echo $quantity ?>, <?php printf('%0.2f', $prodtotal) ?>&#8239;<?php echo $site->currency_symbol() ?></span>

            <?php endif; ?>
            <?php endforeach; ?>
            
            <?php $hello = date('d/m/Y');  
            echo $hello
            ?>
            
         </div>
         <input type="hidden" name="payment_method" value="check">
         <div class="inf">
            <span class="head nobordertop"><?php echo l::get('infocli') ?></span>
            <span><?php echo l::get('email') ?></span><input name="email_cli" placeholder="..." type="email" value="<?php echo $form->old('email_cli'); ?>">
            <span><?php echo l::get('civilite') ?></span>
            <div class="radio">

               <?php $value = $form->old('civilite_cli') ?>
               <label>
                  <!-- Set this as default -->
                  <input type="radio" name="civilite_cli" value="Mme"<?php e($value=='mme', ' checked')?>/> Mme
               </label>
               <label>
                  <input type="radio" name="civilite_cli" value="M"<?php e($value=='m', ' checked')?>/> M
               </label>

            </div>
            <span><?php echo l::get('prenom') ?></span><input class="prenom civ" name="prenom_cli" placeholder="..." value="<?php echo $form->old('prenom_cli'); ?>">
            <span><?php echo l::get('nom') ?></span><input class="nomun border" name="nom_cli" placeholder="..." value="<?php echo $form->old('nom_cli'); ?>">
         </div>
         <div class="fac">
            <span class="head"><?php echo l::get('adressefac') ?></span>
            <span><?php echo l::get('prenom') ?></span><input name="prenom_fac" placeholder="..."  value="<?php echo $form->old('prenom_fac'); ?>">
            <span><?php echo l::get('nom') ?></span><input name="nom_fac" placeholder="..." value="<?php echo $form->old('nom_fac'); ?>">
            <span><?php echo l::get('adresse') ?></span><input name="adresse_fac" placeholder="..." value="<?php echo $form->old('adresse_fac'); ?>">
            <span><?php echo l::get('ville') ?></span><input name="ville_fac" placeholder="..." value="<?php echo $form->old('ville_fac'); ?>">
            <span><?php echo l::get('postal') ?></span><input name="postal_fac" placeholder="..." value="<?php echo $form->old('postal_fac'); ?>">
            <span><?php echo l::get('pays') ?></span><input  class="border" name="pays_fac" placeholder="..." value="<?php echo $form->old('pays_fac'); ?>">
         </div>
         <div class="liv">
            <span class="head"><?php echo l::get('adresseliv') ?></span>
            <span><?php echo l::get('prenom') ?></span><input name="prenom_liv" placeholder="..." value="<?php echo $form->old('prenom_liv'); ?>">
            <span><?php echo l::get('nom') ?></span><input name="nom_liv" placeholder="..."  value="<?php echo $form->old('nom_liv'); ?>">
            <span><?php echo l::get('adresse') ?></span><input name="adresse_liv" placeholder="..." value="<?php echo $form->old('adresse_liv'); ?>">
            <span><?php echo l::get('ville') ?></span><input name="ville_liv" placeholder="..." value="<?php echo $form->old('ville_liv'); ?>">
            <span><?php echo l::get('postal') ?></span><input name="postal_liv" placeholder="..." value="<?php echo $form->old('postal_liv'); ?>">
            <span><?php echo l::get('pays') ?></span><input  class="border" name="pays_liv" placeholder="..." value="<?php echo $form->old('pays_liv'); ?>">
         </div>


         <?php echo csrf_field(); ?>
         <?php echo honeypot_field(); ?>
         <div class="submit">
            <input class="btn" type="submit" value="Envoyer">
         </div>

         <?php if ($form->success()): ?>
         <div class="uniform-errors"><?php echo l::get('msgsuccess') ?></div>
         <?php else: ?>
         <?php snippet('uniform/errors', ['form' => $form]); ?>
         <?php endif; ?>

      </form>
   </section>




</main>



<?php endif; ?>

<?php snippet('footer') ?>

Here is the controller

<?php

use Uniform\Form;

return function ($site, $pages, $page)
{
   $form = new Form([

      'email_cli' => [
         'rules' => ['required', 'email'],
         'message' => l::get('noemailcli'),
      ],
      'prenom_cli' => [
         'rules' => ['required'],
         'message' => l::get('noprenomcli'),
      ],
      'civilite_cli' => [
         'rules' => ['required' => [['mme', 'm']]],
         'message' => l::get('nocivilitecli'),
      ],
      'nom_cli' => [
         'rules' => ['required'],
         'message' => l::get('nonomcli'),
      ],

      'prenom_fac' => [
         'rules' => ['required'],
         'message' => l::get('noprenomfac'),
      ],
      'nom_fac' => [
         'rules' => ['required'],
         'message' => l::get('nonomfac'),
      ],
      'adresse_fac' => [
         'rules' => ['required'],
         'message' => l::get('noadressefac'),
      ],
      'postal_fac' => [
         'rules' => ['required'],
         'message' => l::get('nopostalfac'),
      ],
      'ville_fac' => [
         'rules' => ['required'],
         'message' => l::get('novillefac'),
      ],
      'pays_fac' => [
         'rules' => ['required'],
         'message' => l::get('nopaysfac'),
      ],


      'prenom_liv' => [
         'rules' => ['required'],
         'message' => l::get('noprenomliv'),
      ],
      'nom_liv' => [
         'rules' => ['required'],
         'message' => l::get('nonomliv'),
      ],
      'adresse_liv' => [
         'rules' => ['required'],
         'message' => l::get('noadresseliv'),
      ],
      'postal_liv' => [
         'rules' => ['required'],
         'message' => l::get('nopostalliv'),
      ],
      'ville_liv' => [
         'rules' => ['required'],
         'message' => l::get('novilleliv'),
      ],
      'pays_liv' => [
         'rules' => ['required'],
         'message' => l::get('nopaysliv'),
      ],
   ]);

   if (r::is('POST') && get('payment_method') === 'check') {
      $form->emailAction([
         'to' => 'mymail@yahoo.fr',
         'from' => 'othermail@press.org',
         'service' => 'html-mail',
         'subject' => 'yuhu ',
         'snippet' => 'emails/email',
         'hello' => $hello,
      ])
         ->emailAction([
            'to' => $form->data('email_cli'),
            'from' => 'othermail@press.org',
            'service' => 'html-mail',
            'replyTo' => 'mymail@yahoo.fr',
            'subject' => l::get('subject'),
            'snippet' => 'emails/success',
            'hello' => $hello,
         ]);
   }

   return compact('form');
};

and the e-mail snippet

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
   <head>
      <title>Template email</title>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <style type="text/css">
         @font-face {
	font-family: 'Helvetica Neue LT Pro';
	src: 'blabla base64 very long text' format('woff');
	font-weight: normal;
	font-style: normal;
}
         /* Fonts and Content */
         body, td { font-family: 'Helvetica Neue LT Pro', Helvetica, Arial, sans-serif;;font-weight:normal; font-size:16px;line-height:20px; }
         body { letter-spacing:.05em;background-color: white;color:black; margin: 0; padding: 20px; -webkit-text-size-adjust:none; -ms-text-size-adjust:none; }
         table{width:100%;margin:0;border:0;border-collapse: collapse;}
         tr, th, td{font-weight:normal;vertical-align: top;text-align:left;padding:10px;white-space: nowrap;border:0;border-collapse: collapse}
         td{width:50%}
         .head th{padding:10px 10px 20px 10px}
      </style>

   </head>
   <body style="margin:0; -webkit-text-size-adjust:none;">

      <div style="font-size: 32px;line-height:1em;padding:10px;padding-bottom:30px">
         Chouette, chouette, chouette!<br>
         Vous avez reçu une nouvelle commande.
      </div>
      <table>
         <tr class="head">
            <th><?php echo l::get('adressefac') ?></th>
            <th></th>
            <th><?php echo l::get('adresseliv') ?></th>
            <th></th>
         </tr>
         <tr>
            <th><?php echo l::get('nom') ?></th>
            <th><?php echo $data['nom_fac'] ?></th>
            <th><?php echo l::get('nom') ?></th>
            <th><?php echo $data['nom_liv'] ?></th>
         </tr>
         <tr>
            <th><?php echo l::get('prenom') ?></th>
            <th><?php echo $data['prenom_fac'] ?></th>
            <th><?php echo l::get('prenom') ?></th>
            <th><?php echo $data['prenom_liv'] ?></th>
         </tr>
         <tr>
            <th><?php echo l::get('adresse') ?></th>
            <th><?php echo $data['adresse_fac'] ?></th>
            <th><?php echo l::get('adresse') ?></th>
            <th><?php echo $data['adresse_liv'] ?></th>
         </tr>
         <tr>
            <th><?php echo l::get('postal') ?></th>
            <th><?php echo $data['postal_fac'] ?></th>
            <th><?php echo l::get('postal') ?></th>
            <th><?php echo $data['postal_liv'] ?></th>
         </tr>
         <tr>
            <th><?php echo l::get('ville') ?></th>
            <th><?php echo $data['ville_fac'] ?></th>
            <th><?php echo l::get('ville') ?></th>
            <th><?php echo $data['ville_liv'] ?></th>
         </tr>
         <tr>
            <th><?php echo l::get('pays') ?></th>
            <th><?php echo $data['pays_fac'] ?></th>
            <th><?php echo l::get('pays') ?></th>
            <th><?php echo $data['pays_liv'] ?></th>
         </tr>
         <tr>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
         </tr>
         <tr>
            <th>Produit</th>
            <th>Quantité</th>
            <th>Prix</th>
            <th></th>
         </tr>
         <tr>
            <th><?php echo $options['hello'] ?></th>
            <th><?php echo $data['hello'] ?></th>
            <th></th>
            <th></th>
         </tr>
         <tr>
            <th>-</th>
            <th>-</th>
            <th>-</th>
            <th></th>
         </tr>
         <tr>
            <th>-</th>
            <th>-</th>
            <th>-</th>
            <th></th>
         </tr>
         <tr>
            <th>Sous-total</th>
            <th></th>
            <th>-</th>
            <th></th>
         </tr>
         <tr>
            <th>Frais de port</th>
            <th></th>
            <th>-</th>
            <th></th>
         </tr>
         <tr>
            <th>Total</th>
            <th></th>
            <th>-</th>
            <th></th>
         </tr>
      </table>
      
      <div style="font-size: 32px;line-height:1em;padding:10px;padding-top:30px">
         Dès réception de son paiement, vous pourrez expédier le colis.
      </div>


   </body>
</html>

I see. You retrieve the cart in the template:

$cart = cart_logic(get_cart())

This way the controller and Uniform do not know $cart. Try initializing $cart in the controller, instead:

<?php

use Uniform\Form;

return function ($site, $pages, $page)
{
   $cart = cart_logic(get_cart());

   $form = new Form([
   /* ... */

   $form->emailAction([
      'to' => 'mymail@yahoo.fr',
      'from' => 'othermail@press.org',
      'service' => 'html-mail',
      'subject' => 'yuhu ',
      'snippet' => 'emails/email',
      'cart' => $cart,
   ]);

   /* ... */

   return compact('form', 'cart');
};

Then you should be able to use $options['cart'] in the snippet.

I did what you suggested with $options['cart'] in the snippet, I receive the word “array” inside the mail.
I want to get three things :

  1. <?php echo $product->title()->html() ?>
  2. <?php echo $quantity ?>
  3. <?php printf('%0.2f', $prodtotal) ?> <?php echo $site->currency_symbol() ?>

And these three things are contained inside a foreach loop foreach($cart as $id => $quantity).
How can I display that inside the email.php snippet ?

Try:

foreach($options['cart'] as $id => $quantity):
   //...
1 Like

Well done !!! Thanks you very much for your time, I’ll be able to continue my project.