Source:
https://medium.com/arcana-network-blog/vue-3-composition-api-basics-and-patterns-44813f2c785d
<?php
final class EshopOrderAfterSaveRegister extends Nette\Object {
/**
* Nette callback array of after order save actions
*
* @var array
*/
public $onAfterSave;
/**
* Array with IAfterSaveAction objects
*
* @var array
*/
private $afterSaveActions = array();
/**
* Nette callback array of actions after success payment
*
* @var array
*/
public $onAfterSuccessPayment;
/**
* Array with IAfterSaveAction objects
*
* @var array
*/
private $afterSuccessPaymentActions = array();
/**
* Nette callback array of actions after fail payment
*
* @var array
*/
public $onAfterFailPayment;
/**
* Array with IAfterSaveAction objects
*
* @var array
*/
private $afterFailPaymentActions = array();
/**
* Instance of current presenter
*
* @var Presenter
*/
private $presenter;
/**
* Model EshopOrder
*
* @var EshopOrder
*/
private $modelEshopOrder;
public function __construct(EshopOrder $modelEshopOrder) {
$this->modelEshopOrder = $modelEshopOrder;
}
/**
* Register after save action
*
* @param IAfterSaveAction
*/
public function addAfterSaveAction(IAfterSaveAction $action) {
$this->afterSaveActions[] = $action;
return $this;
}
/**
* Register after success payment action
*
* @param IAfterSaveAction
*/
public function addAfterSuccessPaymentAction(IAfterSaveAction $action) {
$this->afterSuccessPaymentActions[] = $action;
return $this;
}
/**
* Register after success payment action
*
* @param IAfterSaveAction
*/
public function addAfterFailPaymentAction(IAfterSaveAction $action) {
$this->afterFailPaymentActions[] = $action;
return $this;
}
/**
* Application presenter setter
*
* @param Presenter
*/
public function setPresenter(Presenter $presenter) {
$this->presenter = $presenter;
return $this;
}
/**
* Inicialize and invoke after save actions
*
* @param int
* @return void
*/
public function invokeAfterSaveActions($orderId) {
foreach($this->afterSaveActions as $action) {
$action->setPresenter($this->presenter);
$this->onAfterSave[] = array($action, 'doAction');
}
$eshopOrder = $this->modelEshopOrder->getOrder($orderId);
$orderItems = $this->modelEshopOrder->getOrderItems($orderId);
$orderVouchers = $this->modelEshopOrder->getOrderVouchers($orderId);
$this->onAfterSave($eshopOrder, $orderItems, $orderVouchers);
}
/**
* Inicialize and invoke after success payment actions
*
* @param int
* @return void
*/
public function invokeAfterSuccessPaymentActions($orderId) {
foreach($this->afterSuccessPaymentActions as $action) {
$action->setPresenter($this->presenter);
$this->onAfterSuccessPayment[] = array($action, 'doAction');
}
$eshopOrder = $this->modelEshopOrder->getOrder($orderId);
$orderItems = $this->modelEshopOrder->getOrderItems($orderId);
$orderVouchers = $this->modelEshopOrder->getOrderVouchers($orderId);
$this->onAfterSuccessPayment($eshopOrder, $orderItems, $orderVouchers);
}
/**
* Inicialize and invoke after success payment actions
*
* @param int
* @return void
*/
public function invokeAfterFailPaymentActions($orderId) {
foreach($this->afterFailPaymentActions as $action) {
$action->setPresenter($this->presenter);
$this->onAfterFailPayment[] = array($action, 'doAction');
}
$eshopOrder = $this->modelEshopOrder->getOrder($orderId);
$orderItems = $this->modelEshopOrder->getOrderItems($orderId);
$orderVouchers = $this->modelEshopOrder->getOrderVouchers($orderId);
$this->onAfterFailPayment($eshopOrder, $orderItems, $orderVouchers);
}
}
const callback = (entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
// `entry.target` 是 dom 元素
console.log(`${entry.target.id} is visible`);
}
});
};
const options = {
threshold: 1.0,
};
const observer = new IntersectionObserver(callback, options);
const btn = document.getElementById( btn );
const bottomBtn = document.getElementById( bottom-btn );
observer.observe(btn);
observer.observe(bottomBtn);
const detectDeviceType = () =>
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
navigator.userAgent
)
? Mobile
: Desktop ;
console.log(detectDeviceType());
/*
https://jsbin.com/razumivece/edit?css,output
https://jsbin.com/qejuforoba/edit?css,output
*/
header {
position: relative;
background-color: black;
height: 400px;
width: 100%;
overflow: hidden;
}
video {
position: absolute;
top: 50%;
left: 50%;
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
z-index: 0;
transform: translateX(-50%) translateY(-50%);
}
/* or */
video {
position: absolute;
height: 100%;
width: 100%;
object-fit: cover;
}
/*
https://vueschool.io/articles/vuejs-tutorials/what-is-a-vue-js-composable/
*/
/*
Clarity of Data/Methods Source
Mixins = Data Source Obscured
Composables = Transparent Source of Data and Functions
*/
//MyComponent.vue
import ProductMixin from './ProductMixin'
import BrandMixin from './BrandMixin'
import UserMixin from './UserMixin'
export default{
mixins:[ProductMixin, BrandMixin, UserMixin],
created(){
// Where in the world did name come from?
// Let me look through each of the registered mixins to find out
// Oh man, it's not in any of them...
// It must be from a globally registered mixin
console.log(this.site)
// Oh, I got lucky here turns out the first mixin I inspected has the name
console.log(this.name)
}
}
//MyComponent.vue
import useProduct from './useProduct'
import useBrand from './useBrand'
import useUser from './useUser'
export default{
setup(){
const { name } = useProduct()
return { name }
}
created(){
// Where in the world did name come from?
// ah, it's not in setup anywhere... this doesn't exist and is an error
console.log(this.site)
// Oh, nice I can see directly in setup this came from useProduct
console.log(this.name)
}
}
/*
Naming Collisions
Mixins = Risk of Naming Collisions
Composables = NO risk of naming collisions
*/
//MyComponent.vue
import ProductMixin from './ProductMixin' // name = AirMax
import BrandMixin from './BrandMixin' // name = Nike
import UserMixin from './UserMixin' // name = John Doe
export default{
mixins:[ProductMixin, BrandMixin, UserMixin],
created(){
// Actually I'm not so lucky,
// yeah I found the name in ProductMixin
// but turns out UserMixin had a name too
console.log(this.name) // John Doe
}
}
//MyComponent.vue
import useProduct from './useProduct' // name = AirMax
import useBrand from './useBrand' // name = Nike
import useUser from './useUser' // name = John Doe
export default{
setup(){
const { name: productName } = useProduct()
const { name: brandName } = useBrand()
const { name: userName } = useUser()
return { productName, brandName, userName }
}
created(){
// Yay! Nothing is lost and I can get the name of each of the things
// together in my component but when writing the composables
// I don't have to think at all about what variable names might collide
// with names in other composables
console.log(this.productName)
console.log(this.brandName)
console.log(this.userName)
}
}
/*
Mutating Module's Reactive Data from the Component
Mixins = Can NOT Safeguard Own Reactive Data
Composables = Can Safeguard Own Reactive Data
*/
// RequestMixin.js
export default {
data(){
return {
loading: false,
payload: null
}
},
methods:{
async makeRequest(url){
this.loading = true
const res = await fetch(url)
this.payload = await res.json()
this.loading = false
}
}
}
// useRequest.js
import { readonly, ref } from "vue";
export default () => {
// data
const loading = ref(false);
const payload = ref(null);
// methods
const makeRequest = async (url) => {
loading.value = true;
const res = await fetch(url);
payload.value = await res.json();
};
// exposed
return {
payload: readonly(payload), //notice the readonly here
loading: readonly(loading), // and here
makeRequest
};
};
/*
Global State with Composables
*/
//CounterMixins.js
export default{
data(){
return { count: 0 }
},
methods:{
increment(){
this.count ++
}
}
}
//useCounter.js
import {ref, readonly} from 'vue'
export default () => {
const count = ref(0)
const increment = ()=> count.value++
return {
count: readonly(count),
increment
}
}
//useCounter.js
import {ref, readonly} from 'vue'
const count = ref(0)
export default () => {
const increment = ()=> count.value++
return {
count: readonly(count),
increment
}
}
function counter() {
let count = 0;
function increment() {
return count += 1;
};
return increment;
}
const generateId = counter();
generateId(); // 1
generateId(); // 2
generateId(); // 3
// ES 6 ;)
const test = () => {
let temp = 0;
return () => {
temp++;
console.log(temp);
}
}
const invoke = test();
invoke();
invoke();
invoke();
<script>
var audios = [];
audios[0] = new Audio("/sounds/audio_2019-12-20_11-12-44.mp3");
audios[1] = new Audio("/sounds/audio_2019-12-20_11-13-32.mp3");
audios[2] = new Audio("/sounds/audio_2019-12-20_11-13-43.mp3");
audios[3] = new Audio("/sounds/makak-oda.mp3");
var sound;
var playAudio = function(index)
{
for (i = 0; i < audios.length; i++)
{
sound = audios[i];
sound.pause();
sound.currentTime = 0;
}
audios[index].play();
};
</script>
<?php
public function filterAllowedPayments(&$payments)
{
// pokud je v kosiku la degustacion nelze platit kartou
if ($this->isLDBBInBasket() && isset($payments[2])) {
// $payments->where('NOT id', 2);
unset($payments[2]);
}
// pokud je v kosiku merche, neumoznime platbu kartou pri prevzeti
if ($this->isMerchInBasket() && isset($payments[4])) {
// $payments->where('NOT id', 4);
unset($payments[4]);
}
if (!$this->isLDBBInBasket() && isset($payments[4])) {
unset($payments[4]);
}
}
public function filterAllowedTransports(&$transports)
{
// pokud v kosiku neni merche, nelze vyzvednout v ambi kancelari
if (!$this->isMerchInBasket() && isset($transports[2047])) {
// $transports->where('NOT id', 2047);
unset($transports[2047]);
}
}
<?php
namespace Model;
use Nette;
class VatCzSkResolver
{
private static $instance;
public $eshopOrderFormMasoprofit;
public function __construct(EshopOrderFormMasoprofit $eshopOrderFormMasoprofit)
{
self::$instance = $this;
$this->eshopOrderFormMasoprofit = $eshopOrderFormMasoprofit;
}
public static function getDphRewrite()
{
if (!self::$instance) { // nejsme na frontendu
return null;
}
if ($billingAddress = self::$instance->eshopOrderFormMasoprofit->getBillingAddress()) {
if (isset($billingAddress['country_id']) && $billingAddress['country_id'] == 186) {
if (isset($billingAddress['ic_vat']) && $billingAddress['ic_vat'] && isset($billingAddress['dic']) && $billingAddress['dic']) {
return 0;
}
return 20;
}
}
return null;
}
}