Dodanie obsługi danych firmy w formularzach oraz poprawa warunków sprawdzających w kodzie

This commit is contained in:
2025-01-04 12:11:00 +01:00
parent 18dd1718a4
commit 5adfbf5eab
23 changed files with 218 additions and 756 deletions

View File

@@ -10,11 +10,8 @@ ob_start();
<div class="text-big">Numer zamówienia: <b id="order-number"><?= $this -> order[ 'number' ];?></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-number' ); return false;"></i></div> <div class="text-big">Numer zamówienia: <b id="order-number"><?= $this -> order[ 'number' ];?></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-number' ); return false;"></i></div>
<div>Data zamówienia <b><?= $this -> order[ 'date_order' ];?></b></div> <div>Data zamówienia <b><?= $this -> order[ 'date_order' ];?></b></div>
<br> <br>
<div class="text-big">Dane osoby kupującej:</div> <div class="text-big">Dane do dostawy:</div>
<div><b id="order-user-name"><?= $this -> order[ 'client_name' ];?> <?= $this -> order[ 'client_surname' ];?></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-user-name' ); return false;"></i></div> <div><b id="order-user-name"><?= $this -> order[ 'client_name' ];?> <?= $this -> order[ 'client_surname' ];?></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-user-name' ); return false;"></i></div>
<? if ( $this -> order[ 'client_firm' ] ):?>
<div><b><?= $this -> order[ 'client_firm' ];?></b></div>
<? endif;?>
<? if ( $this -> order[ 'client_street' ] ):?> <? if ( $this -> order[ 'client_street' ] ):?>
<div><b id="order-street"><?= $this -> order[ 'client_street' ];?></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-street' ); return false;"></i></div> <div><b id="order-street"><?= $this -> order[ 'client_street' ];?></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-street' ); return false;"></i></div>
<? endif;?> <? endif;?>
@@ -27,7 +24,18 @@ ob_start();
<? endif;?> <? endif;?>
</div> </div>
<div><b><a href="mailto:<?= $this -> order[ 'client_email' ];?>" id="order-user-email"><?= $this -> order[ 'client_email' ];?></a></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-user-email' ); return false;"></i></div> <div><b><a href="mailto:<?= $this -> order[ 'client_email' ];?>" id="order-user-email"><?= $this -> order[ 'client_email' ];?></a></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-user-email' ); return false;"></i></div>
<div><b><a href="tel:<?= $this -> order[ 'client_phone' ];?>" id="order-user-phone"><?= $this -> order[ 'client_phone' ];?></a></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-user-phone' ); return false;"></i></div> <div><b><a href="tel:<?= $this -> order[ 'client_phone' ];?>" id="order-user-phone"><?= preg_replace( "/(\d{3})(\d{3})(\d{3})/", "$1 $2 $3", $this -> order[ 'client_phone' ] );?></a></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-user-phone' ); return false;"></i></div>
<? if ( $this -> order[ 'firm_name' ] ):?>
<br>
<div class="text-big">Dane do faktury:</div>
<div><b id="order-firm-name"><?= $this -> order[ 'firm_name' ];?></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-firm-name' ); return false;"></i></div>
<div><b id="order-firm-street"><?= $this -> order[ 'firm_street' ];?></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-firm-street' ); return false;"></i></div>
<div>
<b id="order-firm-postal-code"><?= $this -> order[ 'firm_postal_code' ];?></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-firm-postal-code' ); return false;"></i>
<b id="order-firm-city"><?= $this -> order[ 'firm_city' ];?></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-firm-city' ); return false;"></i>
</div>
<div>NIP: <b id="order-firm-nip"><?= $this -> order[ 'firm_nip' ];?></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-firm-nip' ); return false;"></i></div>
<? endif;?>
<div class="resend_order_confirmation_email"> <div class="resend_order_confirmation_email">
<button class="btn btn-primary">wyślij ponownie mail z potwierdzeniem zamówienia</button> <button class="btn btn-primary">wyślij ponownie mail z potwierdzeniem zamówienia</button>
</div> </div>

View File

@@ -11,7 +11,7 @@ ob_start();
<div class="text-big">Numer zamówienia: <b id="order-number"><?= $this -> order[ 'number' ];?></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-number' ); return false;"></i></div> <div class="text-big">Numer zamówienia: <b id="order-number"><?= $this -> order[ 'number' ];?></b> <i class="fa fa-copy" onclick="copyToClipboard( 'order-number' ); return false;"></i></div>
<div>Data zamówienia <b><?= $this -> order[ 'date_order' ];?></b></div> <div>Data zamówienia <b><?= $this -> order[ 'date_order' ];?></b></div>
<br> <br>
<div class="text-big">Dane osoby kupującej:</div> <div class="text-big">Dane do dostawy:</div>
<div class="row"> <div class="row">
<div class="col-sm-6"> <div class="col-sm-6">
<input type="text" class="form-control" name="client_name" value="<?= $this -> order[ 'client_name' ];?>" placeholder="Imię"> <input type="text" class="form-control" name="client_name" value="<?= $this -> order[ 'client_name' ];?>" placeholder="Imię">
@@ -20,11 +20,6 @@ ob_start();
<input type="text" class="form-control" name="client_surname" value="<?= $this -> order[ 'client_surname' ];?>" placeholder="Nazwisko"> <input type="text" class="form-control" name="client_surname" value="<?= $this -> order[ 'client_surname' ];?>" placeholder="Nazwisko">
</div> </div>
</div> </div>
<div class="row">
<div class="col-12">
<input type="text" class="form-control" name="client_firm" value="<?= $this -> order[ 'client_firm' ];?>" placeholder="Firma">
</div>
</div>
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<input type="text" class="form-control" name="client_street" value="<?= $this -> order[ 'client_street' ];?>" placeholder="Ulica"> <input type="text" class="form-control" name="client_street" value="<?= $this -> order[ 'client_street' ];?>" placeholder="Ulica">
@@ -48,6 +43,32 @@ ob_start();
<input type="text" class="form-control" name="client_phone" value="<?= $this -> order[ 'client_phone' ];?>" placeholder="Telefon"> <input type="text" class="form-control" name="client_phone" value="<?= $this -> order[ 'client_phone' ];?>" placeholder="Telefon">
</div> </div>
</div> </div>
<? if ( $this -> order['firm_name'] ):?>
<div class="text-big">Dane do faktury:</div>
<div class="row">
<div class="col-12">
<input type="text" class="form-control" name="firm_name" value="<?= $this -> order[ 'firm_name' ];?>" placeholder="Nazwa firmy">
</div>
</div>
<div class="row">
<div class="col-12">
<input type="text" class="form-control" name="firm_street" value="<?= $this -> order[ 'firm_street' ];?>" placeholder="Ulica">
</div>
</div>
<div class="row">
<div class="col-sm-6">
<input type="text" class="form-control" name="firm_postal_code" value="<?= $this -> order[ 'firm_postal_code' ];?>" placeholder="Kod pocztowy">
</div>
<div class="col-sm-6">
<input type="text" class="form-control" name="firm_city" value="<?= $this -> order[ 'firm_city' ];?>" placeholder="Miasto">
</div>
</div>
<div class="row">
<div class="col-12">
<input type="text" class="form-control" name="firm_nip" value="<?= $this -> order[ 'firm_nip' ];?>" placeholder="NIP">
</div>
</div>
<? endif;?>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div>Kwota zamówienia <b><?= $this -> order[ 'summary' ];?> zł</b></div> <div>Kwota zamówienia <b><?= $this -> order[ 'summary' ];?> zł</b></div>
@@ -74,7 +95,7 @@ ob_start();
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<select name="payment_method_id" class="form-control" id="payment_method_id"> <select name="payment_method_id" class="form-control" id="payment_method_id">

View File

@@ -18,9 +18,7 @@ ob_start();
) )
);?> );?>
<? <?
$ver_new = $this->new_ver; $valuemax = ( $this -> new_ver - $this -> ver ) * 1000;
$ver= $this->ver;
$valuemax = ($ver_new - $ver)*1000;
?> ?>
<div class="progress-box hidden"> <div class="progress-box hidden">
<div class="version"> <div class="version">

View File

@@ -9,7 +9,8 @@ class Settings
\S::delete_dir( '../thumbs/' ); \S::delete_dir( '../thumbs/' );
$redis = \RedisConnection::getInstance() -> getConnection(); $redis = \RedisConnection::getInstance() -> getConnection();
$redis -> flushAll(); if ( $redis )
$redis -> flushAll();
\S::alert( 'Cache został wyczyszczony.' ); \S::alert( 'Cache został wyczyszczony.' );
header( 'Location: /admin/dashboard/main_view/' ); header( 'Location: /admin/dashboard/main_view/' );

View File

@@ -31,8 +31,7 @@ class ShopOrder
static public function order_save() static public function order_save()
{ {
if ( \shop\Order::order_save_by_admin( if ( \shop\Order::order_save_by_admin(
\S::get( 'order_id' ), \S::get( 'client_name' ), \S::get( 'client_surname' ), \S::get( 'client_firm' ), \S::get( 'client_street' ), \S::get( 'client_postal_code' ), \S::get( 'client_city' ), \S::get( 'client_email' ), \S::get( 'order_id' ), \S::get( 'client_name' ), \S::get( 'client_surname' ), \S::get( 'client_street' ), \S::get( 'client_postal_code' ), \S::get( 'client_city' ), \S::get( 'client_email' ), \S::get( 'firm_name' ), \S::get( 'firm_street' ), \S::get( 'firm_postal_code' ), \S::get( 'firm_city' ), \S::get( 'firm_nip' ), \S::get( 'transport_id' ), \S::get( 'inpost_paczkomat' ), \S::get( 'payment_method_id' )
\S::get( 'transport_id' ), \S::get( 'inpost_paczkomat' ), \S::get( 'payment_method_id' )
) ) ) )
\S::alert( 'Zamówienie zostało zapisane.' ); \S::alert( 'Zamówienie zostało zapisane.' );

View File

@@ -1285,7 +1285,8 @@ class ShopProduct
\S::delete_dir( '../thumbs/' ); \S::delete_dir( '../thumbs/' );
$redis = \RedisConnection::getInstance() -> getConnection(); $redis = \RedisConnection::getInstance() -> getConnection();
$redis -> flushAll(); if ( $redis )
$redis -> flushAll();
return $product_id; return $product_id;
} }

View File

@@ -373,10 +373,14 @@ class ShopBasket
\S::get( 'phone', true ), \S::get( 'phone', true ),
\S::get( 'name', true ), \S::get( 'name', true ),
\S::get( 'surname', true ), \S::get( 'surname', true ),
\S::get( 'firm', true ),
\S::get( 'street' ), \S::get( 'street' ),
\S::get( 'postal_code', true ), \S::get( 'postal_code', true ),
\S::get( 'city', true ), \S::get( 'city', true ),
\S::get( 'firm_name', true ),
\S::get( 'firm_street', true ),
\S::get( 'firm_postal_code', true ),
\S::get( 'firm_city', true ),
\S::get( 'firm_nip', true ),
\S::get_session( 'basket-inpost-info' ), \S::get_session( 'basket-inpost-info' ),
\S::get_session( 'basket_orlen_point_id' ), \S::get_session( 'basket_orlen_point_id' ),
\S::get_session( 'basket_orlen_point_info' ), \S::get_session( 'basket_orlen_point_info' ),

View File

@@ -63,7 +63,7 @@ class ShopClient
exit; exit;
} }
if ( \front\factory\ShopClient::address_save( $client['id'], \S::get( 'address_id' ), \S::get( 'name', true ), \S::get( 'surname', true ), \S::get( 'firm', true ), \S::get( 'street' ), \S::get( 'postal_code', true ), \S::get( 'city', true ), \S::get( 'phone', true ) ) ) if ( \front\factory\ShopClient::address_save( $client['id'], \S::get( 'address_id' ), \S::get( 'name', true ), \S::get( 'surname', true ), \S::get( 'street' ), \S::get( 'postal_code', true ), \S::get( 'city', true ), \S::get( 'phone', true ) ) )
{ {
\S::get( 'address_id' ) ? \S::alert( \S::lang( 'zmiana-adresu-sukces' ) ) : \S::alert( \S::lang( 'dodawanie-nowego-adresu-sukces' ) ); \S::get( 'address_id' ) ? \S::alert( \S::lang( 'zmiana-adresu-sukces' ) ) : \S::alert( \S::lang( 'dodawanie-nowego-adresu-sukces' ) );
} }

View File

@@ -48,7 +48,7 @@ class ShopClient
return $mdb -> select( 'pp_shop_clients_addresses', '*', [ 'client_id' => (int)$client_id ] ); return $mdb -> select( 'pp_shop_clients_addresses', '*', [ 'client_id' => (int)$client_id ] );
} }
public static function address_save( $client_id, $address_id, $name, $surname, $firm, $street, $postal_code, $city, $phone ) public static function address_save( $client_id, $address_id, $name, $surname, $street, $postal_code, $city, $phone )
{ {
global $mdb; global $mdb;
@@ -58,7 +58,6 @@ class ShopClient
'client_id' => $client_id, 'client_id' => $client_id,
'name' => $name, 'name' => $name,
'surname' => $surname, 'surname' => $surname,
'firm' => $firm,
'street' => $street, 'street' => $street,
'postal_code' => $postal_code, 'postal_code' => $postal_code,
'city' => $city, 'city' => $city,
@@ -71,7 +70,6 @@ class ShopClient
if ( $mdb -> update( 'pp_shop_clients_addresses', [ if ( $mdb -> update( 'pp_shop_clients_addresses', [
'name' => $name, 'name' => $name,
'surname' => $surname, 'surname' => $surname,
'firm' => $firm,
'street' => $street, 'street' => $street,
'postal_code' => $postal_code, 'postal_code' => $postal_code,
'city' => $city, 'city' => $city,

View File

@@ -73,10 +73,14 @@ class ShopOrder
$phone, $phone,
$name, $name,
$surname, $surname,
$firm,
$street, $street,
$postal_code, $postal_code,
$city, $city,
$firm_name,
$firm_street,
$firm_postal_code,
$firm_city,
$firm_nip,
$inpost_info, $inpost_info,
$orlen_point_id, $orlen_point_id,
$orlen_point_info, $orlen_point_info,
@@ -88,7 +92,7 @@ class ShopOrder
if ( $client_id ) if ( $client_id )
$email = \front\factory\ShopClient::client_email( $client_id ); $email = \front\factory\ShopClient::client_email( $client_id );
if ( !is_array( $basket ) or!$transport_id or!$payment_id or!$email or!$phone or!$name or!$surname ) if ( !is_array( $basket ) or !$transport_id or !$payment_id or !$email or !$phone or !$name or !$surname )
return false; return false;
$transport = \front\factory\ShopTransport::transport( $transport_id ); $transport = \front\factory\ShopTransport::transport( $transport_id );
@@ -110,12 +114,16 @@ class ShopOrder
'comment' => null, 'comment' => null,
'client_name' => $name, 'client_name' => $name,
'client_surname' => $surname, 'client_surname' => $surname,
'client_firm' => $firm,
'client_email' => $email, 'client_email' => $email,
'client_street' => $street, 'client_street' => $street,
'client_postal_code' => $postal_code, 'client_postal_code' => $postal_code,
'client_city' => $city, 'client_city' => $city,
'client_phone' => $phone, 'client_phone' => $phone,
'firm_name' => $firm_name ? $firm_name : null,
'firm_street' => $firm_street ? $firm_street : null,
'firm_postal_code' => $firm_postal_code ? $firm_postal_code : null,
'firm_city' => $firm_city ? $firm_city : null,
'firm_nip' => $firm_nip ? $firm_nip : null,
'transport_id' => $transport_id, 'transport_id' => $transport_id,
'transport' => $transport[ 'name_visible' ], 'transport' => $transport[ 'name_visible' ],
'transport_cost' => $transport_cost, 'transport_cost' => $transport_cost,

View File

@@ -423,7 +423,7 @@ class Order implements \ArrayAccess
} }
// ADMIN - zmiana zamówienia // ADMIN - zmiana zamówienia
static public function order_save_by_admin( int $order_id, string $client_name, string $client_surname, string $client_firm, string $client_street, string $client_postal_code, string $client_city, string $client_email, static public function order_save_by_admin( int $order_id, string $client_name, string $client_surname, string $client_street, string $client_postal_code, string $client_city, string $client_email, $firm_name = '', $firm_street = '', $firm_postal_code = '', $firm_city = '', $firm_nip = '',
int $transport_id, string $inpost_paczkomat, int $payment_method_id ) int $transport_id, string $inpost_paczkomat, int $payment_method_id )
{ {
global $mdb, $user; global $mdb, $user;
@@ -431,11 +431,15 @@ class Order implements \ArrayAccess
$mdb -> update( 'pp_shop_orders', [ $mdb -> update( 'pp_shop_orders', [
'client_name' => $client_name, 'client_name' => $client_name,
'client_surname' => $client_surname, 'client_surname' => $client_surname,
'client_firm' => $client_firm,
'client_street' => $client_street, 'client_street' => $client_street,
'client_postal_code' => $client_postal_code, 'client_postal_code' => $client_postal_code,
'client_city' => $client_city, 'client_city' => $client_city,
'client_email' => $client_email, 'client_email' => $client_email,
'firm_name' => $firm_name ? $firm_name : null,
'firm_street' => $firm_street ? $firm_street : null,
'firm_postal_code' => $firm_postal_code ? $firm_postal_code : null,
'firm_city' => $firm_city ? $firm_city : null,
'firm_nip' => $firm_nip ? $firm_nip : null,
'transport_id' => $transport_id, 'transport_id' => $transport_id,
'transport' => $mdb -> get( 'pp_shop_transports', 'name_visible', [ 'id' => $transport_id ] ), 'transport' => $mdb -> get( 'pp_shop_transports', 'name_visible', [ 'id' => $transport_id ] ),
'transport_cost' => $mdb -> get( 'pp_shop_transports', 'cost', [ 'id' => $transport_id ] ), 'transport_cost' => $mdb -> get( 'pp_shop_transports', 'cost', [ 'id' => $transport_id ] ),

View File

@@ -83,8 +83,7 @@ function parseOrlenAddress( $input )
} }
} }
function getImageUrlById ($id ) function getImageUrlById($id) {
{
$apiUrl = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'] . '/api/v1/product.php'; $apiUrl = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'] . '/api/v1/product.php';
$ch = curl_init(); $ch = curl_init();
@@ -92,14 +91,13 @@ function getImageUrlById ($id )
curl_setopt($ch, CURLOPT_URL, $apiUrl . '?id=' . urlencode($id)); curl_setopt($ch, CURLOPT_URL, $apiUrl . '?id=' . urlencode($id));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array( curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json', 'Content-Type: application/json',
)); ));
$response = curl_exec($ch); $response = curl_exec($ch);
if ( $response === false ) if ($response === false) {
{ curl_close($ch);
curl_close($ch); return null;
return null;
} }
curl_close($ch); curl_close($ch);
@@ -542,7 +540,7 @@ if ( $apilo_settings['enabled'] and $apilo_settings['sync_orders'] and $apilo_se
$postData = [ $postData = [
'idExternal' => $order['id'], 'idExternal' => $order['id'],
'isInvoice' => false, 'isInvoice' => $order['firm_name'] ? true : false,
'customerLogin' => $order['client_email'], 'customerLogin' => $order['client_email'],
'paymentType' => (int)\front\factory\ShopPaymentMethod::get_apilo_payment_method_id( $order['payment_method_id'] ), 'paymentType' => (int)\front\factory\ShopPaymentMethod::get_apilo_payment_method_id( $order['payment_method_id'] ),
'originalCurrency' => 'PLN', 'originalCurrency' => 'PLN',
@@ -574,6 +572,15 @@ if ( $apilo_settings['enabled'] and $apilo_settings['sync_orders'] and $apilo_se
'platformId' => $apilo_settings['platform-id'] 'platformId' => $apilo_settings['platform-id']
]; ];
if ( $order['firm_name'] )
{
$postData['addressInvoice']['name'] = $order['firm_name'];
$postData['addressInvoice']['streetName'] = $order['firm_street'];
$postData['addressInvoice']['city'] = $order['firm_city'];
$postData['addressInvoice']['zipCode'] = $order['firm_postal_code'];
$postData['addressInvoice']['companyTaxNumber'] = $order['firm_nip'];
}
// jeżeli paczkomat // jeżeli paczkomat
if ( $order['inpost_paczkomat'] ) if ( $order['inpost_paczkomat'] )
{ {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -2602,6 +2602,13 @@ ul.pager {
width: 100%; width: 100%;
} }
.fvat-data {
display: none;
padding: 15px 15px 5px 15px;
background: #FFF;
margin-bottom: 15px;
}
.addresses { .addresses {
.address { .address {
width: calc(100% / 2 - 10px); width: calc(100% / 2 - 10px);
@@ -2829,6 +2836,30 @@ ul.pager {
.top { .top {
padding-bottom: 50px; padding-bottom: 50px;
} }
.top-second {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
padding-bottom: 25px;
@include respond-below(sm) {
grid-template-columns: 1fr;
}
.column {
padding: 20px;
background: #FFF;
}
h5 {
font-weight: 600;
}
p {
margin-bottom: 0;
}
}
} }
.order-bottom { .order-bottom {

View File

@@ -1,41 +0,0 @@
/**
* jQuery MotionCAPTCHA Plugin CSS
* josscrowcroft.com/projects/motioncaptcha-jquery-plugin/
*
* Only these rules are absolutely necessary for the plugin.
* NB. The width & height of the canvas can be flexible to fit your layout but there's a recommended min/max
* - if you need it much bigger/smaller, you could tweak the background-positions of the shape classes.
*/
/* The canvas: */
#mc-canvas {
width:220px; /* For best results, set width to between 210px and 240px */
height:154px; /* For best results, set height to between 140px and 170px */
background:#fff -9999px -9999px no-repeat;
background-image: url('motionCaptcha-shapes.jpg') !important;
}
/* The shapes: */
#mc-canvas.triangle { background-position: 10px 10px }
#mc-canvas.x { background-position:-200px 10px }
#mc-canvas.rectangle { background-position:-400px 10px }
#mc-canvas.circle { background-position:-600px 10px }
#mc-canvas.check { background-position: 10px -150px }
#mc-canvas.caret { background-position:-200px -150px }
#mc-canvas.zigzag { background-position:-400px -150px }
#mc-canvas.arrow { background-position:-600px -150px }
#mc-canvas.leftbracket { background-position: 10px -300px }
#mc-canvas.rightbracket { background-position:-200px -300px }
#mc-canvas.v { background-position:-400px -300px }
#mc-canvas.delete { background-position:-600px -300px }
#mc-canvas.leftbrace { background-position: 10px -450px }
#mc-canvas.rightbrace { background-position:-200px -450px }
#mc-canvas.star { background-position:-400px -450px }
#mc-canvas.pigtail { background-position:-600px -450px }
/* Disable mouse-selection on the page (only while user is actively drawing on the canvas): */
.mc-noselect {
-webkit-user-select: none,
-moz-user-select: none,
user-select: none
}

View File

@@ -1,654 +0,0 @@
/*!
* jQuery MotionCAPTCHA v0.2
*
* Proof of concept only for now, check the roadmap to see when it will be ready for wider use!
*
* http://josscrowcroft.com/projects/motioncaptcha-jquery-plugin/
*
* DEMO: http://josscrowcroft.com/demos/motioncaptcha/
* CODE: https://github.com/josscrowcroft/MotionCAPTCHA
*
* Copyright (c) 2011 Joss Crowcroft - joss[at]josscrowcroftcom | http://www.josscrowcroft.com
*
* Incoporates other open source projects, attributed below.
*/
jQuery.fn.motionCaptcha || (function($) {
/**
* Main plugin function definition
*/
$.fn.motionCaptcha = function(options) {
/**
* Act on matched form element:
* This could be set up to iterate over multiple elements, but tbh would it ever be useful?
*/
return this.each(function() {
// Build main options before element iteration:
var opts = $.extend({}, $.fn.motionCaptcha.defaults, options);
// Ensure option ID params are valid #selectors:
opts.actionId = '#' + opts.actionId.replace(/\#/g, '');
opts.canvasId = '#' + opts.canvasId.replace(/\#/g, '');
opts.divId = '#' + opts.divId.replace(/\#/g, '');
opts.submitId = ( opts.submitId ) ? '#' + opts.submitId.replace(/\#/g, '') : false;
// Plugin setup:
// Set up Harmony vars:
var brush,
locked = false;
// Set up MotionCAPTCHA form and jQuery elements:
var $body = $('body'),
$form = $(this),
$container = $(opts.divId),
$canvas = $(opts.canvasId);
// Set up MotionCAPTCHA canvas vars:
var canvasWidth = $canvas.width(),
canvasHeight = $canvas.height(),
borderLeftWidth = 1 * $canvas.css('borderLeftWidth').replace('px', ''),
borderTopWidth = 1 * $canvas.css('borderTopWidth').replace('px', '');
// Canvas setup:
// Set the canvas DOM element's dimensions to match the display width/height (pretty important):
$canvas[0].width = canvasWidth;
$canvas[0].height = canvasHeight;
// Get DOM reference to canvas context:
var ctx = $canvas[0].getContext("2d");
// Add canvasWidth and canvasHeight values to context, for Ribbon brush:
ctx.canvasWidth = canvasWidth;
ctx.canvasHeight = canvasHeight;
// Set canvas context font and fillStyle:
ctx.font = opts.canvasFont;
ctx.fillStyle = opts.canvasTextColor;
// Set random shape
$canvas.addClass( opts.shapes[Math.floor(Math.random() * (opts.shapes.length) )] );
// Set up Dollar Recognizer and drawing vars:
var _isDown = false,
_holdStill = false,
_points = [],
_r = new DollarRecognizer();
// Create the Harmony Ribbon brush:
brush = new Ribbon(ctx);
// Mousedown event
// Start Harmony brushstroke and begin recording DR points:
var touchStartEvent = function(event) {
if ( locked )
return false;
// Prevent default action:
event.preventDefault();
// Get mouse position inside the canvas:
var pos = getPos(event),
x = pos[0],
y = pos[1];
// Internal drawing var
_isDown = true;
// Prevent jumpy-touch bug on android, no effect on other platforms:
_holdStill = true;
// Disable text selection:
$('body').addClass('mc-noselect');
// Clear canvas:
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
// Start brushstroke:
brush.strokeStart(x, y);
// Remove 'mc-invalid' and 'mc-valid' classes from canvas:
$canvas.removeClass('mc-invalid mc-valid');
// Add the first point to the points array:
_points = [NewPoint(x, y)];
return false;
}; // mousedown/touchstart event
// Mousemove event:
var touchMoveEvent = function(event) {
if ( _holdStill ) {
return _holdStill = 0;
}
// If mouse is down and canvas not locked:
if ( !locked && _isDown ) {
// Prevent default action:
event.preventDefault();
// Get mouse position inside the canvas:
var pos = getPos(event),
x = pos[0],
y = pos[1];
// Append point to points array:
_points[_points.length] = NewPoint(x, y);
// Do brushstroke:
brush.stroke(x, y);
}
return false;
}; // mousemove/touchmove event
// Mouseup event:
var touchEndEvent = function(event) {
// If mouse is down and canvas not locked:
if ( !locked && _isDown ) {
_isDown = false;
// Allow text-selection again:
$('body').removeClass('mc-noselect');
// Dollar Recognizer result:
if (_points.length >= 10) {
var result = _r.Recognize(_points);
// Check result:
if ( $canvas.attr('class').match(result.Name) && result.Score > 0.7 ) {
// Lock the canvas:
locked = 1;
// Destroy the Harmony brush (give it time to finish drawing)
setTimeout( brush.destroy, 500 );
// Add 'mc-valid' class to canvas:
$canvas.addClass('mc-valid');
// Write success message into canvas:
ctx.fillText(opts.successMsg, 10, 24);
// Call the onSuccess function to handle the rest of the business:
// Pass in the form, the canvas, the canvas context:
opts.onSuccess($form, $canvas, ctx);
} else {
// Add 'mc-invalid' class to canvas:
$canvas.addClass('mc-invalid');
// Write error message into canvas:
ctx.fillText(opts.errorMsg, 10, 24);
// Pass off to the error callback to finish up:
opts.onError($form, $canvas, ctx);
}
} else { // fewer than 10 points were recorded:
// Add 'mc-invalid' class to canvas:
$canvas.addClass('mc-invalid');
// Write error message into canvas:
ctx.fillText(opts.errorMsg, 10, 24);
// Pass off to the error callback to finish up:
opts.onError($form, $canvas, ctx);
}
}
return false;
}; // mouseup/touchend event
// Bind events to canvas:
$canvas.bind({
mousedown: touchStartEvent,
mousemove: touchMoveEvent,
mouseup: touchEndEvent,
});
// Mobile touch events:
$canvas[0].addEventListener('touchstart', touchStartEvent, false);
$canvas[0].addEventListener('touchmove', touchMoveEvent, false);
$canvas[0].addEventListener('touchend', touchEndEvent, false);
// Add active CSS class to form:
$form.addClass(opts.cssClass.replace(/\./, ''))
/**
* Get X/Y mouse position, relative to (/inside) the canvas
*
* Handles cross-browser quirks rather nicely, I feel.
*
* @todo For 1.0, if no way to obtain coordinates, don't activate MotionCAPTCHA.
*/
function getPos(event) {
var x, y;
// Check for mobile first to avoid android jumpy-touch bug (iOS / Android):
if ( event.touches && event.touches.length > 0 ) {
// iOS/android uses event.touches, relative to entire page:
x = event.touches[0].pageX - $canvas.offset().left + borderLeftWidth;
y = event.touches[0].pageY - $canvas.offset().top + borderTopWidth;
} else if ( event.offsetX ) {
// Chrome/Safari give the event offset relative to the target event:
x = event.offsetX - borderLeftWidth;
y = event.offsetY - borderTopWidth;
} else {
// Otherwise, subtract page click from canvas offset (Firefox uses this):
x = event.pageX - $canvas.offset().left - borderLeftWidth;
y = event.pageY - $canvas.offset().top - borderTopWidth;
}
return [x,y];
}
}); // this.each
} // end main plugin function
/**
* Exposed default plugin settings, which can be overridden in plugin call.
*/
$.fn.motionCaptcha.defaults = {
actionId: '#mc-action', // The ID of the input containing the form action
divId: '#mc', // If you use an ID other than '#mc' for the placeholder, pass it in here
canvasId: '#mc-canvas', // The ID of the MotionCAPTCHA canvas element
submitId: false, // If your form has multiple submit buttons, give the ID of the main one here
cssClass: '.mc-active', // This CSS class is applied to the form, when the plugin is active
// An array of shape names that you want MotionCAPTCHA to use:
shapes: ['triangle', 'x', 'rectangle', 'circle', 'check', 'caret', 'zigzag', 'arrow', 'leftbracket', 'rightbracket', 'v', 'delete', 'star', 'pigtail'],
// Canvas vars:
canvasFont: '15px "Lucida Grande"',
canvasTextColor: '#111',
// These messages are displayed inside the canvas after a user finishes drawing:
errorMsg: 'Please try again.',
successMsg: 'Captcha passed!',
// This message is displayed if the user's browser doesn't support canvas:
noCanvasMsg: "Your browser doesn't support <canvas> - try Chrome, FF4, Safari or IE9.",
// This could be any HTML string (eg. '<label>Draw this shit yo:</label>'):
label: '<p>Please draw the shape in the box to submit the form:</p>',
// Callback function to execute when a user successfully draws the shape
// Passed in the form, the canvas and the canvas context
// Scope (this) is active plugin options object (opts)
// NB: The default onSuccess callback function enables the submit button, and adds the form action attribute:
onSuccess: function($form, $canvas, ctx) {
var opts = this,
$submit = opts.submitId ? $form.find(opts.submitId) : $form.find('input[type=submit]:disabled');
// Set the form action:
$form.attr( 'action', $(opts.actionId).val() );
// Enable the submit button:
$submit.prop('disabled', false);
$( '#contact-form-send' ).removeAttr( 'disabled' );
return;
},
// Callback function to execute when a user successfully draws the shape
// Passed in the form, the canvas and the canvas context
// Scope (this) is active plugin options object (opts)
onError: function($form, $canvas, ctx) {
var opts = this;
return;
}
};
/*!
* Harmony | mrdoob | Ribbon Brush class
* http://mrdoob.com/projects/harmony/
*/
function Ribbon( ctx ) {
this.init( ctx );
}
Ribbon.prototype = {
ctx: null,
X: null,
Y: null,
painters: null,
interval: null,
init: function( ctx ) {
var scope = this,
userAgent = navigator.userAgent.toLowerCase(),
brushSize = ( userAgent.search("android") > -1 || userAgent.search("iphone") > -1 ) ? 2 : 1,
strokeColor = [0, 0, 0];
this.ctx = ctx;
this.ctx.globalCompositeOperation = 'source-over';
this.X = this.ctx.canvasWidth / 2;
this.Y = this.ctx.canvasHeight / 2;
this.painters = [];
// Draw each of the lines:
for ( var i = 0; i < 38; i++ ) {
this.painters.push({
dx: this.ctx.canvasWidth / 2,
dy: this.ctx.canvasHeight / 2,
ax: 0,
ay: 0,
div: 0.1,
ease: Math.random() * 0.18 + 0.60
});
}
// Set the ticker:
this.interval = setInterval( update, 1000/60 );
function update() {
var i;
scope.ctx.lineWidth = brushSize;
scope.ctx.strokeStyle = "rgba(" + strokeColor[0] + ", " + strokeColor[1] + ", " + strokeColor[2] + ", " + 0.06 + ")";
for ( i = 0; i < scope.painters.length; i++ ) {
scope.ctx.beginPath();
scope.ctx.moveTo(scope.painters[i].dx, scope.painters[i].dy);
scope.painters[i].dx -= scope.painters[i].ax = (scope.painters[i].ax + (scope.painters[i].dx - scope.X) * scope.painters[i].div) * scope.painters[i].ease;
scope.painters[i].dy -= scope.painters[i].ay = (scope.painters[i].ay + (scope.painters[i].dy - scope.Y) * scope.painters[i].div) * scope.painters[i].ease;
scope.ctx.lineTo(scope.painters[i].dx, scope.painters[i].dy);
scope.ctx.stroke();
}
}
},
destroy: function() {
clearInterval(this.interval);
},
strokeStart: function( X, Y ) {
this.X = X;
this.Y = Y
for (var i = 0; i < this.painters.length; i++) {
this.painters[i].dx = X;
this.painters[i].dy = Y;
}
this.shouldDraw = true;
},
stroke: function( X, Y ) {
this.X = X;
this.Y = Y;
}
};
/*!
* The $1 Unistroke Recognizer
* http://depts.washington.edu/aimgroup/proj/dollar/
*
* Jacob O. Wobbrock, Ph.D. | wobbrock@u.washington.edu
* Andrew D. Wilson, Ph.D. | awilson@microsoft.com
* Yang Li, Ph.D. | yangli@cs.washington.edu
*
* Modified to include the Protractor gesture recognizing algorithm
* http://www.yangl.org/pdf/protractor-chi2010.pdf
*
* Adapted and modified for purpose by Joss Crowcroft
* http://www.josscrowcroft.com
*
* The original software is distributed under the "New BSD License" agreement
*
* Copyright (c) 2007-2011, Jacob O. Wobbrock, Andrew D. Wilson and Yang Li. All rights reserved.
**/
// Point class
function Point(x, y) {
this.X = x;
this.Y = y;
}
// Wrapper for Point class (saves mega kb when compressing the template definitions):
function NewPoint(x, y) {
return new Point(x, y)
}
// Rectangle class
function Rectangle(x, y, width, height) {
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
}
// Template class: a unistroke template
function Template(name, points) {
this.Name = name;
this.Points = Resample(points, NumPoints);
var radians = IndicativeAngle(this.Points);
this.Points = RotateBy(this.Points, -radians);
this.Points = ScaleTo(this.Points, SquareSize);
this.Points = TranslateTo(this.Points, Origin);
this.Vector = Vectorize(this.Points); // for Protractor
}
// Result class
function Result(name, score) {
this.Name = name;
this.Score = score;
}
// DollarRecognizer class constants
var NumTemplates = 16,
NumPoints = 64,
SquareSize = 250.0,
Origin = NewPoint(0,0);
// DollarRecognizer class
function DollarRecognizer() {
// Predefined templates for each gesture type:
this.Templates = [];
this.Templates.push( new Template("triangle", [NewPoint(137,139),NewPoint(135,141),NewPoint(133,144),NewPoint(132,146),NewPoint(130,149),NewPoint(128,151),NewPoint(126,155),NewPoint(123,160),NewPoint(120,166),NewPoint(116,171),NewPoint(112,177),NewPoint(107,183),NewPoint(102,188),NewPoint(100,191),NewPoint(95,195),NewPoint(90,199),NewPoint(86,203),NewPoint(82,206),NewPoint(80,209),NewPoint(75,213),NewPoint(73,213),NewPoint(70,216),NewPoint(67,219),NewPoint(64,221),NewPoint(61,223),NewPoint(60,225),NewPoint(62,226),NewPoint(65,225),NewPoint(67,226),NewPoint(74,226),NewPoint(77,227),NewPoint(85,229),NewPoint(91,230),NewPoint(99,231),NewPoint(108,232),NewPoint(116,233),NewPoint(125,233),NewPoint(134,234),NewPoint(145,233),NewPoint(153,232),NewPoint(160,233),NewPoint(170,234),NewPoint(177,235),NewPoint(179,236),NewPoint(186,237),NewPoint(193,238),NewPoint(198,239),NewPoint(200,237),NewPoint(202,239),NewPoint(204,238),NewPoint(206,234),NewPoint(205,230),NewPoint(202,222),NewPoint(197,216),NewPoint(192,207),NewPoint(186,198),NewPoint(179,189),NewPoint(174,183),NewPoint(170,178),NewPoint(164,171),NewPoint(161,168),NewPoint(154,160),NewPoint(148,155),NewPoint(143,150),NewPoint(138,148),NewPoint(136,148)]) );
this.Templates.push( new Template("x", [NewPoint(87,142),NewPoint(89,145),NewPoint(91,148),NewPoint(93,151),NewPoint(96,155),NewPoint(98,157),NewPoint(100,160),NewPoint(102,162),NewPoint(106,167),NewPoint(108,169),NewPoint(110,171),NewPoint(115,177),NewPoint(119,183),NewPoint(123,189),NewPoint(127,193),NewPoint(129,196),NewPoint(133,200),NewPoint(137,206),NewPoint(140,209),NewPoint(143,212),NewPoint(146,215),NewPoint(151,220),NewPoint(153,222),NewPoint(155,223),NewPoint(157,225),NewPoint(158,223),NewPoint(157,218),NewPoint(155,211),NewPoint(154,208),NewPoint(152,200),NewPoint(150,189),NewPoint(148,179),NewPoint(147,170),NewPoint(147,158),NewPoint(147,148),NewPoint(147,141),NewPoint(147,136),NewPoint(144,135),NewPoint(142,137),NewPoint(140,139),NewPoint(135,145),NewPoint(131,152),NewPoint(124,163),NewPoint(116,177),NewPoint(108,191),NewPoint(100,206),NewPoint(94,217),NewPoint(91,222),NewPoint(89,225),NewPoint(87,226),NewPoint(87,224)]) );
this.Templates.push( new Template("rectangle", [NewPoint(78,149),NewPoint(78,153),NewPoint(78,157),NewPoint(78,160),NewPoint(79,162),NewPoint(79,164),NewPoint(79,167),NewPoint(79,169),NewPoint(79,173),NewPoint(79,178),NewPoint(79,183),NewPoint(80,189),NewPoint(80,193),NewPoint(80,198),NewPoint(80,202),NewPoint(81,208),NewPoint(81,210),NewPoint(81,216),NewPoint(82,222),NewPoint(82,224),NewPoint(82,227),NewPoint(83,229),NewPoint(83,231),NewPoint(85,230),NewPoint(88,232),NewPoint(90,233),NewPoint(92,232),NewPoint(94,233),NewPoint(99,232),NewPoint(102,233),NewPoint(106,233),NewPoint(109,234),NewPoint(117,235),NewPoint(123,236),NewPoint(126,236),NewPoint(135,237),NewPoint(142,238),NewPoint(145,238),NewPoint(152,238),NewPoint(154,239),NewPoint(165,238),NewPoint(174,237),NewPoint(179,236),NewPoint(186,235),NewPoint(191,235),NewPoint(195,233),NewPoint(197,233),NewPoint(200,233),NewPoint(201,235),NewPoint(201,233),NewPoint(199,231),NewPoint(198,226),NewPoint(198,220),NewPoint(196,207),NewPoint(195,195),NewPoint(195,181),NewPoint(195,173),NewPoint(195,163),NewPoint(194,155),NewPoint(192,145),NewPoint(192,143),NewPoint(192,138),NewPoint(191,135),NewPoint(191,133),NewPoint(191,130),NewPoint(190,128),NewPoint(188,129),NewPoint(186,129),NewPoint(181,132),NewPoint(173,131),NewPoint(162,131),NewPoint(151,132),NewPoint(149,132),NewPoint(138,132),NewPoint(136,132),NewPoint(122,131),NewPoint(120,131),NewPoint(109,130),NewPoint(107,130),NewPoint(90,132),NewPoint(81,133),NewPoint(76,133)]) );
this.Templates.push( new Template("circle", [NewPoint(127,141),NewPoint(124,140),NewPoint(120,139),NewPoint(118,139),NewPoint(116,139),NewPoint(111,140),NewPoint(109,141),NewPoint(104,144),NewPoint(100,147),NewPoint(96,152),NewPoint(93,157),NewPoint(90,163),NewPoint(87,169),NewPoint(85,175),NewPoint(83,181),NewPoint(82,190),NewPoint(82,195),NewPoint(83,200),NewPoint(84,205),NewPoint(88,213),NewPoint(91,216),NewPoint(96,219),NewPoint(103,222),NewPoint(108,224),NewPoint(111,224),NewPoint(120,224),NewPoint(133,223),NewPoint(142,222),NewPoint(152,218),NewPoint(160,214),NewPoint(167,210),NewPoint(173,204),NewPoint(178,198),NewPoint(179,196),NewPoint(182,188),NewPoint(182,177),NewPoint(178,167),NewPoint(170,150),NewPoint(163,138),NewPoint(152,130),NewPoint(143,129),NewPoint(140,131),NewPoint(129,136),NewPoint(126,139)]) );
this.Templates.push( new Template("check", [NewPoint(91,185),NewPoint(93,185),NewPoint(95,185),NewPoint(97,185),NewPoint(100,188),NewPoint(102,189),NewPoint(104,190),NewPoint(106,193),NewPoint(108,195),NewPoint(110,198),NewPoint(112,201),NewPoint(114,204),NewPoint(115,207),NewPoint(117,210),NewPoint(118,212),NewPoint(120,214),NewPoint(121,217),NewPoint(122,219),NewPoint(123,222),NewPoint(124,224),NewPoint(126,226),NewPoint(127,229),NewPoint(129,231),NewPoint(130,233),NewPoint(129,231),NewPoint(129,228),NewPoint(129,226),NewPoint(129,224),NewPoint(129,221),NewPoint(129,218),NewPoint(129,212),NewPoint(129,208),NewPoint(130,198),NewPoint(132,189),NewPoint(134,182),NewPoint(137,173),NewPoint(143,164),NewPoint(147,157),NewPoint(151,151),NewPoint(155,144),NewPoint(161,137),NewPoint(165,131),NewPoint(171,122),NewPoint(174,118),NewPoint(176,114),NewPoint(177,112),NewPoint(177,114),NewPoint(175,116),NewPoint(173,118)]) );
this.Templates.push( new Template("caret", [NewPoint(79,245),NewPoint(79,242),NewPoint(79,239),NewPoint(80,237),NewPoint(80,234),NewPoint(81,232),NewPoint(82,230),NewPoint(84,224),NewPoint(86,220),NewPoint(86,218),NewPoint(87,216),NewPoint(88,213),NewPoint(90,207),NewPoint(91,202),NewPoint(92,200),NewPoint(93,194),NewPoint(94,192),NewPoint(96,189),NewPoint(97,186),NewPoint(100,179),NewPoint(102,173),NewPoint(105,165),NewPoint(107,160),NewPoint(109,158),NewPoint(112,151),NewPoint(115,144),NewPoint(117,139),NewPoint(119,136),NewPoint(119,134),NewPoint(120,132),NewPoint(121,129),NewPoint(122,127),NewPoint(124,125),NewPoint(126,124),NewPoint(129,125),NewPoint(131,127),NewPoint(132,130),NewPoint(136,139),NewPoint(141,154),NewPoint(145,166),NewPoint(151,182),NewPoint(156,193),NewPoint(157,196),NewPoint(161,209),NewPoint(162,211),NewPoint(167,223),NewPoint(169,229),NewPoint(170,231),NewPoint(173,237),NewPoint(176,242),NewPoint(177,244),NewPoint(179,250),NewPoint(181,255),NewPoint(182,257)]) );
this.Templates.push( new Template("zigzag", [NewPoint(307,216),NewPoint(333,186),NewPoint(356,215),NewPoint(375,186),NewPoint(399,216),NewPoint(418,186)]) );
this.Templates.push( new Template("arrow", [NewPoint(68,222),NewPoint(70,220),NewPoint(73,218),NewPoint(75,217),NewPoint(77,215),NewPoint(80,213),NewPoint(82,212),NewPoint(84,210),NewPoint(87,209),NewPoint(89,208),NewPoint(92,206),NewPoint(95,204),NewPoint(101,201),NewPoint(106,198),NewPoint(112,194),NewPoint(118,191),NewPoint(124,187),NewPoint(127,186),NewPoint(132,183),NewPoint(138,181),NewPoint(141,180),NewPoint(146,178),NewPoint(154,173),NewPoint(159,171),NewPoint(161,170),NewPoint(166,167),NewPoint(168,167),NewPoint(171,166),NewPoint(174,164),NewPoint(177,162),NewPoint(180,160),NewPoint(182,158),NewPoint(183,156),NewPoint(181,154),NewPoint(178,153),NewPoint(171,153),NewPoint(164,153),NewPoint(160,153),NewPoint(150,154),NewPoint(147,155),NewPoint(141,157),NewPoint(137,158),NewPoint(135,158),NewPoint(137,158),NewPoint(140,157),NewPoint(143,156),NewPoint(151,154),NewPoint(160,152),NewPoint(170,149),NewPoint(179,147),NewPoint(185,145),NewPoint(192,144),NewPoint(196,144),NewPoint(198,144),NewPoint(200,144),NewPoint(201,147),NewPoint(199,149),NewPoint(194,157),NewPoint(191,160),NewPoint(186,167),NewPoint(180,176),NewPoint(177,179),NewPoint(171,187),NewPoint(169,189),NewPoint(165,194),NewPoint(164,196)]) );
this.Templates.push( new Template("leftbracket", [NewPoint(140,124),NewPoint(138,123),NewPoint(135,122),NewPoint(133,123),NewPoint(130,123),NewPoint(128,124),NewPoint(125,125),NewPoint(122,124),NewPoint(120,124),NewPoint(118,124),NewPoint(116,125),NewPoint(113,125),NewPoint(111,125),NewPoint(108,124),NewPoint(106,125),NewPoint(104,125),NewPoint(102,124),NewPoint(100,123),NewPoint(98,123),NewPoint(95,124),NewPoint(93,123),NewPoint(90,124),NewPoint(88,124),NewPoint(85,125),NewPoint(83,126),NewPoint(81,127),NewPoint(81,129),NewPoint(82,131),NewPoint(82,134),NewPoint(83,138),NewPoint(84,141),NewPoint(84,144),NewPoint(85,148),NewPoint(85,151),NewPoint(86,156),NewPoint(86,160),NewPoint(86,164),NewPoint(86,168),NewPoint(87,171),NewPoint(87,175),NewPoint(87,179),NewPoint(87,182),NewPoint(87,186),NewPoint(88,188),NewPoint(88,195),NewPoint(88,198),NewPoint(88,201),NewPoint(88,207),NewPoint(89,211),NewPoint(89,213),NewPoint(89,217),NewPoint(89,222),NewPoint(88,225),NewPoint(88,229),NewPoint(88,231),NewPoint(88,233),NewPoint(88,235),NewPoint(89,237),NewPoint(89,240),NewPoint(89,242),NewPoint(91,241),NewPoint(94,241),NewPoint(96,240),NewPoint(98,239),NewPoint(105,240),NewPoint(109,240),NewPoint(113,239),NewPoint(116,240),NewPoint(121,239),NewPoint(130,240),NewPoint(136,237),NewPoint(139,237),NewPoint(144,238),NewPoint(151,237),NewPoint(157,236),NewPoint(159,237)]) );
this.Templates.push( new Template("rightbracket", [NewPoint(112,138),NewPoint(112,136),NewPoint(115,136),NewPoint(118,137),NewPoint(120,136),NewPoint(123,136),NewPoint(125,136),NewPoint(128,136),NewPoint(131,136),NewPoint(134,135),NewPoint(137,135),NewPoint(140,134),NewPoint(143,133),NewPoint(145,132),NewPoint(147,132),NewPoint(149,132),NewPoint(152,132),NewPoint(153,134),NewPoint(154,137),NewPoint(155,141),NewPoint(156,144),NewPoint(157,152),NewPoint(158,161),NewPoint(160,170),NewPoint(162,182),NewPoint(164,192),NewPoint(166,200),NewPoint(167,209),NewPoint(168,214),NewPoint(168,216),NewPoint(169,221),NewPoint(169,223),NewPoint(169,228),NewPoint(169,231),NewPoint(166,233),NewPoint(164,234),NewPoint(161,235),NewPoint(155,236),NewPoint(147,235),NewPoint(140,233),NewPoint(131,233),NewPoint(124,233),NewPoint(117,235),NewPoint(114,238),NewPoint(112,238)]) );
this.Templates.push( new Template("v", [NewPoint(89,164),NewPoint(90,162),NewPoint(92,162),NewPoint(94,164),NewPoint(95,166),NewPoint(96,169),NewPoint(97,171),NewPoint(99,175),NewPoint(101,178),NewPoint(103,182),NewPoint(106,189),NewPoint(108,194),NewPoint(111,199),NewPoint(114,204),NewPoint(117,209),NewPoint(119,214),NewPoint(122,218),NewPoint(124,222),NewPoint(126,225),NewPoint(128,228),NewPoint(130,229),NewPoint(133,233),NewPoint(134,236),NewPoint(136,239),NewPoint(138,240),NewPoint(139,242),NewPoint(140,244),NewPoint(142,242),NewPoint(142,240),NewPoint(142,237),NewPoint(143,235),NewPoint(143,233),NewPoint(145,229),NewPoint(146,226),NewPoint(148,217),NewPoint(149,208),NewPoint(149,205),NewPoint(151,196),NewPoint(151,193),NewPoint(153,182),NewPoint(155,172),NewPoint(157,165),NewPoint(159,160),NewPoint(162,155),NewPoint(164,150),NewPoint(165,148),NewPoint(166,146)]) );
this.Templates.push( new Template("delete", [NewPoint(123,129),NewPoint(123,131),NewPoint(124,133),NewPoint(125,136),NewPoint(127,140),NewPoint(129,142),NewPoint(133,148),NewPoint(137,154),NewPoint(143,158),NewPoint(145,161),NewPoint(148,164),NewPoint(153,170),NewPoint(158,176),NewPoint(160,178),NewPoint(164,183),NewPoint(168,188),NewPoint(171,191),NewPoint(175,196),NewPoint(178,200),NewPoint(180,202),NewPoint(181,205),NewPoint(184,208),NewPoint(186,210),NewPoint(187,213),NewPoint(188,215),NewPoint(186,212),NewPoint(183,211),NewPoint(177,208),NewPoint(169,206),NewPoint(162,205),NewPoint(154,207),NewPoint(145,209),NewPoint(137,210),NewPoint(129,214),NewPoint(122,217),NewPoint(118,218),NewPoint(111,221),NewPoint(109,222),NewPoint(110,219),NewPoint(112,217),NewPoint(118,209),NewPoint(120,207),NewPoint(128,196),NewPoint(135,187),NewPoint(138,183),NewPoint(148,167),NewPoint(157,153),NewPoint(163,145),NewPoint(165,142),NewPoint(172,133),NewPoint(177,127),NewPoint(179,127),NewPoint(180,125)]) );
this.Templates.push( new Template("star", [NewPoint(75,250),NewPoint(75,247),NewPoint(77,244),NewPoint(78,242),NewPoint(79,239),NewPoint(80,237),NewPoint(82,234),NewPoint(82,232),NewPoint(84,229),NewPoint(85,225),NewPoint(87,222),NewPoint(88,219),NewPoint(89,216),NewPoint(91,212),NewPoint(92,208),NewPoint(94,204),NewPoint(95,201),NewPoint(96,196),NewPoint(97,194),NewPoint(98,191),NewPoint(100,185),NewPoint(102,178),NewPoint(104,173),NewPoint(104,171),NewPoint(105,164),NewPoint(106,158),NewPoint(107,156),NewPoint(107,152),NewPoint(108,145),NewPoint(109,141),NewPoint(110,139),NewPoint(112,133),NewPoint(113,131),NewPoint(116,127),NewPoint(117,125),NewPoint(119,122),NewPoint(121,121),NewPoint(123,120),NewPoint(125,122),NewPoint(125,125),NewPoint(127,130),NewPoint(128,133),NewPoint(131,143),NewPoint(136,153),NewPoint(140,163),NewPoint(144,172),NewPoint(145,175),NewPoint(151,189),NewPoint(156,201),NewPoint(161,213),NewPoint(166,225),NewPoint(169,233),NewPoint(171,236),NewPoint(174,243),NewPoint(177,247),NewPoint(178,249),NewPoint(179,251),NewPoint(180,253),NewPoint(180,255),NewPoint(179,257),NewPoint(177,257),NewPoint(174,255),NewPoint(169,250),NewPoint(164,247),NewPoint(160,245),NewPoint(149,238),NewPoint(138,230),NewPoint(127,221),NewPoint(124,220),NewPoint(112,212),NewPoint(110,210),NewPoint(96,201),NewPoint(84,195),NewPoint(74,190),NewPoint(64,182),NewPoint(55,175),NewPoint(51,172),NewPoint(49,170),NewPoint(51,169),NewPoint(56,169),NewPoint(66,169),NewPoint(78,168),NewPoint(92,166),NewPoint(107,164),NewPoint(123,161),NewPoint(140,162),NewPoint(156,162),NewPoint(171,160),NewPoint(173,160),NewPoint(186,160),NewPoint(195,160),NewPoint(198,161),NewPoint(203,163),NewPoint(208,163),NewPoint(206,164),NewPoint(200,167),NewPoint(187,172),NewPoint(174,179),NewPoint(172,181),NewPoint(153,192),NewPoint(137,201),NewPoint(123,211),NewPoint(112,220),NewPoint(99,229),NewPoint(90,237),NewPoint(80,244),NewPoint(73,250),NewPoint(69,254),NewPoint(69,252)]) );
this.Templates.push( new Template("pigtail", [NewPoint(81,219),NewPoint(84,218),NewPoint(86,220),NewPoint(88,220),NewPoint(90,220),NewPoint(92,219),NewPoint(95,220),NewPoint(97,219),NewPoint(99,220),NewPoint(102,218),NewPoint(105,217),NewPoint(107,216),NewPoint(110,216),NewPoint(113,214),NewPoint(116,212),NewPoint(118,210),NewPoint(121,208),NewPoint(124,205),NewPoint(126,202),NewPoint(129,199),NewPoint(132,196),NewPoint(136,191),NewPoint(139,187),NewPoint(142,182),NewPoint(144,179),NewPoint(146,174),NewPoint(148,170),NewPoint(149,168),NewPoint(151,162),NewPoint(152,160),NewPoint(152,157),NewPoint(152,155),NewPoint(152,151),NewPoint(152,149),NewPoint(152,146),NewPoint(149,142),NewPoint(148,139),NewPoint(145,137),NewPoint(141,135),NewPoint(139,135),NewPoint(134,136),NewPoint(130,140),NewPoint(128,142),NewPoint(126,145),NewPoint(122,150),NewPoint(119,158),NewPoint(117,163),NewPoint(115,170),NewPoint(114,175),NewPoint(117,184),NewPoint(120,190),NewPoint(125,199),NewPoint(129,203),NewPoint(133,208),NewPoint(138,213),NewPoint(145,215),NewPoint(155,218),NewPoint(164,219),NewPoint(166,219),NewPoint(177,219),NewPoint(182,218),NewPoint(192,216),NewPoint(196,213),NewPoint(199,212),NewPoint(201,211)]) );
// $1 Gesture Recognizer API (now using Protractor instead)
this.Recognize = function(points) {
var b = +Infinity,
t = 0,
radians,
i,
score,
vector;
points = Resample(points, NumPoints);
radians = IndicativeAngle(points);
points = RotateBy(points, -radians);
vector = Vectorize(points); // for Protractor
for (i = 0; i < this.Templates.length; i++) {
var d = OptimalCosineDistance(this.Templates[i].Vector, vector);
if (d < b) {
b = d; // best (least) distance
t = i; // unistroke template
}
}
return new Result(this.Templates[t].Name, 1 / b);
};
}
// Helper functions:
function Resample(points, n) {
var I = PathLength(points) / (n - 1), // interval length
D = 0.0,
newpoints = new Array(points[0]),
i;
for (i = 1; i < points.length; i++) {
var d = Distance(points[i - 1], points[i]);
if ((D + d) >= I) {
var qx = points[i - 1].X + ((I - D) / d) * (points[i].X - points[i - 1].X),
qy = points[i - 1].Y + ((I - D) / d) * (points[i].Y - points[i - 1].Y),
q = NewPoint(qx, qy);
newpoints[newpoints.length] = q; // append new point 'q'
points.splice(i, 0, q); // insert 'q' at position i in points s.t. 'q' will be the next i
D = 0.0;
}
else D += d;
}
// somtimes we fall a rounding-error short of adding the last point, so add it if so
if (newpoints.length == n - 1) {
newpoints[newpoints.length] = NewPoint(points[points.length - 1].X, points[points.length - 1].Y);
}
return newpoints;
}
function IndicativeAngle(points) {
var c = Centroid(points);
return Math.atan2(c.Y - points[0].Y, c.X - points[0].X);
}
function RotateBy(points, radians) {
var c = Centroid(points),
cos = Math.cos(radians),
sin = Math.sin(radians),
newpoints = [],
i;
for (i = 0; i < points.length; i++) {
var qx = (points[i].X - c.X) * cos - (points[i].Y - c.Y) * sin + c.X,
qy = (points[i].X - c.X) * sin + (points[i].Y - c.Y) * cos + c.Y;
newpoints[newpoints.length] = NewPoint(qx, qy);
}
return newpoints;
}
function ScaleTo(points, size) {
var B = BoundingBox(points),
newpoints = [],
i;
for (i = 0; i < points.length; i++) {
var qx = points[i].X * (size / B.Width),
qy = points[i].Y * (size / B.Height);
newpoints[newpoints.length] = NewPoint(qx, qy);
}
return newpoints;
}
function TranslateTo(points, pt) {
var c = Centroid(points),
newpoints = [],
i;
for (i = 0; i < points.length; i++) {
var qx = points[i].X + pt.X - c.X,
qy = points[i].Y + pt.Y - c.Y;
newpoints[newpoints.length] = NewPoint(qx, qy);
}
return newpoints;
}
function Vectorize(points) { // for Protractor
var sum = 0.0,
vector = [],
i,
magnitude;
for ( i = 0; i < points.length; i++) {
vector[vector.length] = points[i].X;
vector[vector.length] = points[i].Y;
sum += points[i].X * points[i].X + points[i].Y * points[i].Y;
}
magnitude = Math.sqrt(sum);
for ( i = 0; i < vector.length; i++ )
vector[i] /= magnitude;
return vector;
}
function OptimalCosineDistance(v1, v2) { // for Protractor
var a = 0.0,
b = 0.0,
i,
angle;
for (i = 0; i < v1.length; i += 2) {
a += v1[i] * v2[i] + v1[i + 1] * v2[i + 1];
b += v1[i] * v2[i + 1] - v1[i + 1] * v2[i];
}
angle = Math.atan(b / a);
return Math.acos(a * Math.cos(angle) + b * Math.sin(angle));
}
function Centroid(points) {
var x = 0.0,
y = 0.0,
i;
for (i = 0; i < points.length; i++) {
x += points[i].X;
y += points[i].Y;
}
x /= points.length;
y /= points.length;
return NewPoint(x, y);
}
function BoundingBox(points) {
var minX = +Infinity,
maxX = -Infinity,
minY = +Infinity,
maxY = -Infinity,
i;
for (i = 0; i < points.length; i++) {
if (points[i].X < minX)
minX = points[i].X;
if (points[i].X > maxX)
maxX = points[i].X;
if (points[i].Y < minY)
minY = points[i].Y;
if (points[i].Y > maxY)
maxY = points[i].Y;
}
return new Rectangle(minX, minY, maxX - minX, maxY - minY);
}
function PathLength(points) {
var d = 0.0,
i;
for (i = 1; i < points.length; i++) {
d += Distance(points[i - 1], points[i]);
}
return d;
}
function Distance(p1, p2) {
var dx = p2.X - p1.X,
dy = p2.Y - p1.Y;
return Math.sqrt(dx * dx + dy * dy);
}
})(jQuery);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -51,13 +51,8 @@
<input type="text" id="surname" name="surname" class="form-control" required placeholder="<?= ucfirst( \S::lang( 'nazwisko' ) );?>" value="<?= htmlspecialchars( $address_current['surname'] );?>"> <input type="text" id="surname" name="surname" class="form-control" required placeholder="<?= ucfirst( \S::lang( 'nazwisko' ) );?>" value="<?= htmlspecialchars( $address_current['surname'] );?>">
</div> </div>
</div> </div>
<div class="form-group row">
<div class="col-12">
<input type="text" id="firm" name="firm" class="form-control" placeholder="<?= ucfirst( \S::lang( 'firma' ) );?> (<?= \S::lang( 'opcjonalnie' );?>)" value="<?= htmlspecialchars( $address_current['firm'] );?>">
</div>
</div>
<div class="form-group"> <div class="form-group">
<input type="text" id="street" name="street" class="form-control" <? if ( !in_array( $this -> transport_method['id'], [ 1, 2, 3, 9] ) ):?> required<? endif;?> placeholder="<?= ucfirst( \S::lang( 'ulica-i-nr-domu' ) );?> <? if ( in_array( $this -> transport_method['id'], [ 1, 2, 3, 9] ) ):?> (<?= \S::lang( 'opcjonalnie' );?>)<? endif;?>" value="<?= htmlspecialchars( $address_current['street'] );?>"> <input type="text" id="street" name="street" class="form-control" <? if ( !in_array( $this -> transport_method['id'], [ 1, 2, 3, 9] ) ):?> required<? endif;?> placeholder="<?= ucfirst( \S::lang( 'ulica-i-nr-domu' ) );?> <? if ( in_array( $this -> transport_method['id'], [ 1, 2, 3, 9] ) ):?> (<?= \S::lang( 'opcjonalnie' );?>)<? endif;?>" value="<?= htmlspecialchars( $address_current['street'] );?>">
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="row"> <div class="row">
@@ -75,17 +70,51 @@
<img src="/images/system/lang_pl.png" alt=""> <img src="/images/system/lang_pl.png" alt="">
<span>+48</span> <span>+48</span>
</div> </div>
<input <input type="tel" id="phone" name="phone" class="form-control form-control-input" required placeholder="<?= ucfirst(\S::lang('telefon')); ?>" value="<?= htmlspecialchars($address_current['phone']); ?>" pattern="[0-9]{9}">
type="tel"
id="phone"
name="phone"
class="form-control form-control-input"
required
placeholder="<?= ucfirst(\S::lang('telefon')); ?>"
value="<?= htmlspecialchars($address_current['phone']); ?>"
pattern="[0-9]{9}">
</div> </div>
</div> </div>
<div class="form-group">
<div class="row">
<div class="col-12" id="fvat">
<input type="checkbox" name="fvat">
<?= \S::lang( 'faktura-vat' );?>
</div>
</div>
</div>
<div class="fvat-data">
<div class="form-group">
<div class="row">
<div class="col-12">
<input type="text" id="firm_name" name="firm_name" class="form-control" placeholder="<?= ucfirst( \S::lang( 'nazwa-firmy' ) );?>" value="">
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-12">
<input type="text" id="firm_street" name="firm_street" class="form-control" placeholder="<?= ucfirst( \S::lang( 'ulica-i-nr-domu' ) );?>" value="">
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-12 col-md-6">
<input type="text" id="firm_postal_code" name="firm_postal_code" pattern="[0-9]{2}-[0-9]{3}" title="Format xx-xxx" class="form-control" placeholder="<?= ucfirst( \S::lang( 'kod-pocztowy' ) );?>" value="">
</div>
<div class="col-12 col-md-6">
<input type="text" id="firm_city" name="firm_city" class="form-control" placeholder="<?= ucfirst( \S::lang( 'miasto' ) );?>" value="">
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-12">
<input type="text" id="firm_nip" name="firm_nip" class="form-control" placeholder="<?= ucfirst( \S::lang( 'nip' ) );?>" value="">
</div>
</div>
</div>
</div>
<div class="form-group"> <div class="form-group">
<div class="row"> <div class="row">
<div class="col-12" id="agreement"> <div class="col-12" id="agreement">
@@ -110,10 +139,11 @@
</div> </div>
<script class="footer"> <script class="footer">
$(document).ready(function () { $(document).ready(function () {
function validatePhone() { function validatePhone() {
var phone = $('#phone'); var phone = $('#phone');
var phonePattern = /^[0-9]{9}$/; var phonePattern = /^[0-9]{9}$/;
if (!phone.val() || !phonePattern.test(phone.val())) { if (!phone.val() || !phonePattern.test(phone.val())) {
$('#order-send').prop('disabled', true); $('#order-send').prop('disabled', true);
} else { } else {
@@ -128,7 +158,18 @@
validatePhone(); validatePhone();
}); });
$( function() { $( function()
{
$( 'body' ).on( 'change', 'input[name="fvat"]', function() {
if ( $( this ).is( ':checked' ) ) {
$( '.fvat-data input' ).prop( 'required', true );
$( '.fvat-data' ).slideDown();
} else {
$( '.fvat-data' ).slideUp();
$( '.fvat-data input' ).prop( 'required', false ).val( '' );
}
});
$( 'body' ).on( click_event, '.addresses .address .btn-select', function(e) $( 'body' ).on( click_event, '.addresses .address .btn-select', function(e)
{ {
e.preventDefault(); e.preventDefault();

View File

@@ -15,9 +15,6 @@
<div class="form-group"> <div class="form-group">
<input type="text" name="surname" required class="form-control" placeholder="<?= ucfirst( \S::lang( 'nazwisko' ) );?>" value="<?= htmlspecialchars( $this -> address['surname'] );?>"> <input type="text" name="surname" required class="form-control" placeholder="<?= ucfirst( \S::lang( 'nazwisko' ) );?>" value="<?= htmlspecialchars( $this -> address['surname'] );?>">
</div> </div>
<div class="form-group">
<input type="text" name="firm" class="form-control" placeholder="<?= ucfirst( \S::lang( 'firma' ) );?> (<?= \S::lang( 'opcjonalnie' );?>)" value="<?= htmlspecialchars( $this -> address['firm'] );?>">
</div>
<div class="form-group"> <div class="form-group">
<input type="text" name="street" required class="form-control" placeholder="<?= ucfirst( \S::lang( 'ulica-i-numer' ) );?>" value="<?= htmlspecialchars( $this -> address['street'] );?>"> <input type="text" name="street" required class="form-control" placeholder="<?= ucfirst( \S::lang( 'ulica-i-numer' ) );?>" value="<?= htmlspecialchars( $this -> address['street'] );?>">
</div> </div>

View File

@@ -41,6 +41,16 @@ echo $this -> settings['newsletter_header'];
<br /><br />Punkt Orlen: <b><?= $this -> order['orlen_point'];?> <br /><br />Punkt Orlen: <b><?= $this -> order['orlen_point'];?>
<? endif;?> <? endif;?>
</p> </p>
<? if ( $this -> order['firm_name'] ):?>
<div style="border-bottom: 1px solid #eee; margin-bottom: 15px;"></div>
<p style="font-family: Arial; font-size: 14px; font-weight: 600; text-transform: uppercase;"><?= \S::lang( 'dane-do-faktury' );?>:</p>
<p style="font-family: Arial; font-size: 14px; margin-top: 15px;">
<?= $this -> order['firm_name'];?><br />
<?= $this -> order['firm_street'];?><br />
<?= $this -> order['firm_postal_code'];?> <?= $this -> order['firm_city'];?><br />
NIP: <?= $this -> order['firm_nip'];?>
</p>
<? endif;?>
<div style="border-bottom: 1px solid #eee; margin-bottom: 15px;"></div> <div style="border-bottom: 1px solid #eee; margin-bottom: 15px;"></div>
<p style="font-family: Arial; font-size: 14px; font-weight: 600; text-transform: uppercase;"><?= \S::lang( 'zamowione-produkty' );?>:</p> <p style="font-family: Arial; font-size: 14px; font-weight: 600; text-transform: uppercase;"><?= \S::lang( 'zamowione-produkty' );?>:</p>
<table style="font-family: Arial; width: 100%; max-width: 800px; border-collapse: collapse; font-size: 14px; margin-bottom: 25px;"> <table style="font-family: Arial; width: 100%; max-width: 800px; border-collapse: collapse; font-size: 14px; margin-bottom: 25px;">

View File

@@ -7,6 +7,35 @@
Status zamówienia: <span><?= $this -> statuses[ $this -> order['status'] ];?></span> Status zamówienia: <span><?= $this -> statuses[ $this -> order['status'] ];?></span>
</div> </div>
</div> </div>
<div class="top-second">
<div class="column">
<h5><?= ucfirst( \S::lang( 'dane-do-dostawy' ) );?></h5>
<p>
<?= $this -> order['client_surname'];?> <?= $this -> order['client_name'];?><br />
<?= $this -> order['client_street'];?><br />
<?= $this -> order['client_postal_code'];?> <?= $this -> order['client_city'];?><br />
<?= $this -> order['client_email'];?><br />
<?= $this -> order['client_phone'];?>
<? if ( $this -> order['inpost_paczkomat'] ):?>
<br /><br />Paczkomat: <b><?= $this -> order['inpost_paczkomat'];?>
<? endif;?>
<? if ( $this -> order['orlen_point'] ):?>
<br /><br />Punkt Orlen: <b><?= $this -> order['orlen_point'];?>
<? endif;?>
</p>
</div>
<div class="column">
<? if ( $this -> order['firm_name'] ):?>
<h5><?= \S::lang( 'dane-do-faktury' );?>:</h5>
<p>
<?= $this -> order['firm_name'];?><br />
<?= $this -> order['firm_street'];?><br />
<?= $this -> order['firm_postal_code'];?> <?= $this -> order['firm_city'];?><br />
NIP: <?= $this -> order['firm_nip'];?>
</p>
<? endif;?>
</div>
</div>
<div class="products"> <div class="products">
<? if ( is_array( $this -> order['products'] ) and count( $this -> order['products'] ) ):?> <? if ( is_array( $this -> order['products'] ) and count( $this -> order['products'] ) ):?>
<? foreach ( $this -> order['products'] as $product ):?> <? foreach ( $this -> order['products'] as $product ):?>

View File

@@ -56,7 +56,7 @@
<div class="price-minimal"> <div class="price-minimal">
Najniższa cena w ciągu ostatnich 30 dni: <strong><?= \shop\Shop::shortPrice( \front\factory\ShopProduct::get_minimal_price( $this -> product['id'], $this -> product -> price_brutto_promo ) );?> zł</strong> Najniższa cena w ciągu ostatnich 30 dni: <strong><?= \shop\Shop::shortPrice( \front\factory\ShopProduct::get_minimal_price( $this -> product['id'], $this -> product -> price_brutto_promo ) );?> zł</strong>
</div> </div>
<? if ( $this -> product -> weight && $this -> product -> product_unit_id ):?> <? if ( $this -> product -> weight > 0 && $this -> product -> product_unit_id ):?>
<div class="price_weight"> <div class="price_weight">
<?= \shop\Shop::shortPrice( $this -> product -> price_brutto_promo / $this -> product -> wegiht * 1 );?> <?= $this -> product -> product_unit;?> <?= \shop\Shop::shortPrice( $this -> product -> price_brutto_promo / $this -> product -> wegiht * 1 );?> <?= $this -> product -> product_unit;?>
</div> </div>
@@ -65,7 +65,7 @@
<div class="price"> <div class="price">
<?= \shop\Shop::shortPrice( $this -> product -> price_brutto );?> <span class="small">zł</span> <?= \shop\Shop::shortPrice( $this -> product -> price_brutto );?> <span class="small">zł</span>
</div> </div>
<? if ( $this -> product -> weight && $this -> product -> product_unit_id ):?> <? if ( $this -> product -> weight > 0 && $this -> product -> product_unit_id ):?>
<div class="price_weight"> <div class="price_weight">
<?= \shop\Shop::shortPrice( $this -> product -> price_brutto / $this -> product -> weight );?> <span class="small">zł</span> / <?= \front\factory\Dictionaries::get_name_by_id( $this -> product -> product_unit_id, $this -> lang_id );?> <?= \shop\Shop::shortPrice( $this -> product -> price_brutto / $this -> product -> weight );?> <span class="small">zł</span> / <?= \front\factory\Dictionaries::get_name_by_id( $this -> product -> product_unit_id, $this -> lang_id );?>
</div> </div>