'paymentskechiqcom', 'USD' => 'kechiqfashionbrandsUSD', 'GBP' => 'kechiqfashionbrandsGBP', 'AUD' => 'kechiqfashionbrandsAUD', 'AED' => 'kechiqfashionbrandsAED', 'DKK' => 'kechiqfashionbrandsDKK', 'PLN' => 'kechiqfashionbrandsPLN', 'RON' => 'kechiqfashionbrandsRON', 'SEK' => 'kechiqfashionbrandsSEK', ]); define('BRAINTREE_GOOGLE_PAY_MERCHANT_ID', ''); define('BRAINTREE_MERCHANT_DISPLAY_NAME', 'Kechiq'); define('BRAINTREE_PAYMENTS_METHODS', ['CREDIT_CARD', 'PAYPAL']); /** * Zoorate - Feedaty */ define('ZOORATE_FEEDATY_MERCHANT_CODE', '10215058'); define('ZOORATE_FEEDATY_CLIENT_SECRET', 'cb365a5347a3491e8208d227ed77a90e'); /** * Mailchimp */ define('MAILCHIMP_API_KEY', '3474cc4a161c4e935a9091e546aebdc9-us18'); define('MAILCHIMP_SERVER_PREFIX', 'us18'); define('MAILCHIMP_LIST_ID', 'f2009c0216'); /** * Scalapay */ define('SCALAPAY_API_KEY', 'sp_1ane91akps0ajik'); /** * Cache Type */ define('CACHE_TYPE', 'sqlite'); /** * Cache Credentials (Redis) */ define('CACHE_REDIS_HOST', 'redis-kechiq-v2-cache.uy7owr.0001.euw1.cache.amazonaws.com'); define('CACHE_REDIS_PORT', '6379'); define('CACHE_REDIS_USER', 'kechiq'); define('CACHE_REDIS_PASSWORD', 'HFXqK75qhhqRafHEp2AHRcN8'); /** * Host images */ define('HOST_IMAGES', sprintf('%s://%s%s', (( $_SERVER['HTTPS'] == 'on' ) ? 'https' : 'http'), $_SERVER['SERVER_NAME'], $hostFolderPath)); /** * Databse queries log */ define('DB_QUERY_LOG', false); [ * "url_to_override" => "assigned_view" * ] * * Example * "it" => [ * "contatti" => "contacts" * ] * * @var array */ $system_routes = []; /** * IT — Rewrite url */ $system_routes["it"] = [ 'uomo' => 'gender_mens', 'donna' => 'gender_womens', 'brands' => 'all_brands', 'promo' => 'products_promo', 'best-sellers' => 'best_sellers', 'featured' => 'products_featured', 'luxury' => 'products_luxury', 'registrati-come-azienda' => 'signup_business', 'vendi-con-kechiq' => 'sell_with_kechiq', 'diventa-rivenditore' => 'become_reseller', 'piani-e-tariffe' => 'plans_and_pricing', 'concept-boutique' => 'concept_boutique', 'concept-boutique-dubai' => 'concept_boutique_dubai', 'concept-boutique-milano' => 'concept_boutique_milano', 'trend' => 'trend', 'idee-regalo' => 'gift_ideas', // Info page 'chi-siamo' => 'about', 'privacy' => 'privacy', 'metodi-di-pagamento' => 'payment_methods', 'spedizioni' => 'shipping', 'resi' => 'returns', 'termini' => 'terms', 'impressum' => 'impressum', 'help' => 'help', 'note-legali' => 'legal_notes', 'startup-innovativa' => 'innovative_startup', 'protezione-acquisti' => 'insurance_purchase' ]; /** * EN — Rewrite url */ $system_routes["en"] = [ 'man' => 'gender_mens', 'woman' => 'gender_womens', 'brands' => 'all_brands', 'promo' => 'products_promo', 'best-sellers' => 'best_sellers', 'featured' => 'products_featured', 'luxury' => 'products_luxury', 'business-signup' => 'signup_business', 'sell-with-kechiq' => 'sell_with_kechiq', 'become-reseller' => 'become_reseller', 'plans-and-pricing' => 'plans_and_pricing', 'concept-boutique' => 'concept_boutique', 'concept-boutique-dubai' => 'concept_boutique_dubai', 'concept-boutique-milano' => 'concept_boutique_milano', 'trend' => 'trend', 'gift-ideas' => 'gift_ideas', // Info page 'about' => 'about', 'privacy' => 'privacy', 'payment-methods' => 'payment_methods', 'shipping' => 'shipping', 'returns' => 'returns', 'terms' => 'terms', 'impressum' => 'impressum', 'help' => 'help', 'legal-notes' => 'legal_notes', 'innovative-startup' => 'innovative_startup', 'insurance-purchase' => 'insurance_purchase' ]; /** * FR — Rewrite url */ $system_routes["fr"] = [ 'homme' => 'gender_mens', 'femme' => 'gender_womens', 'brands' => 'all_brands', 'promo' => 'products_promo', 'meilleures-ventes' => 'best_sellers', 'featured' => 'products_featured', 'luxury' => 'products_luxury', 'entreprise-inscrivez' => 'signup_business', 'vendez-avec-kechiq' => 'sell_with_kechiq', 'devenir-detaillant' => 'become_reseller', 'plans-et-tarifs' => 'plans_and_pricing', 'concept-boutique' => 'concept_boutique', 'concept-boutique-dubai' => 'concept_boutique_dubai', 'concept-boutique-milano' => 'concept_boutique_milano', 'tendance' => 'trend', 'idees-de-cadeau' => 'gift_ideas', // Info page 'qui-sommes-nous' => 'about', 'privacy' => 'privacy', 'modes-de-paiement' => 'payment_methods', 'expedition-et-livraison' => 'shipping', 'retours-et-remboursements' => 'returns', 'conditions-de-ventes' => 'terms', 'impressum' => 'impressum', 'aide' => 'help', 'notes-legales' => 'legal_notes', 'innovative-startup' => 'innovative_startup', 'protection-des-achats' => 'insurance_purchase', 'trend' => 'trend', 'gift-ideas' => 'gift_ideas', ]; /** * DE — Rewrite url */ $system_routes["de"] = [ 'mann' => 'gender_mens', 'frau' => 'gender_womens', 'brands' => 'all_brands', 'promo' => 'products_promo', 'unsere-bestseller' => 'best_sellers', 'featured' => 'products_featured', 'luxury' => 'products_luxury', 'business-signup' => 'signup_business', 'verkaufen-mit-kechiq' => 'sell_with_kechiq', 'werden-sie-verkaufer' => 'become_reseller', 'plane-und-tarife' => 'plans_and_pricing', 'concept-boutique' => 'concept_boutique', 'concept-boutique-dubai' => 'concept_boutique_dubai', 'concept-boutique-milano' => 'concept_boutique_milano', 'trend' => 'trend', 'geschenkideen' => 'gift_ideas', // Info page 'das-unternehmen' => 'about', 'datenschutzerklarung' => 'privacy', 'zahlungsarten' => 'payment_methods', 'versendung-und-ablieferung' => 'shipping', 'ruckversand-und-erstattungen' => 'returns', 'allgemeine-geschaftsbedingungen' => 'terms', 'impressum' => 'impressum', 'hilfe' => 'help', 'rechtliche-hinweise' => 'legal_notes', 'innovative-startup' => 'innovative_startup', 'kaufschutz' => 'insurance_purchase' ]; /** * ES — Rewrite url */ $system_routes["es"] = [ 'hombre' => 'gender_mens', 'mujer' => 'gender_womens', 'brands' => 'all_brands', 'promo' => 'products_promo', 'bestsellere' => 'best_sellers', 'featured' => 'products_featured', 'luxury' => 'products_luxury', 'registro-empresa' => 'signup_business', 'venda-con-kechiq' => 'sell_with_kechiq', 'ser-un-revendedor' => 'become_reseller', 'planos-y-tarifarios' => 'plans_and_pricing', 'concept-boutique' => 'concept_boutique', 'concept-boutique-dubai' => 'concept_boutique_dubai', 'concept-boutique-milano' => 'concept_boutique_milano', 'tendencia' => 'trend', 'ideas-de-regalo' => 'gift_ideas', // Info page 'quienes-somos' => 'about', 'proteccion-de-datos' => 'privacy', 'metodos-de-pago' => 'payment_methods', 'envio-y-entrega' => 'shipping', 'devoluciones-y-reembolsos' => 'returns', 'terminos-y-condiciones' => 'terms', 'impressum' => 'impressum', 'ayuda' => 'help', 'notas-legales' => 'legal_notes', 'innovative-startup' => 'innovative_startup', 'compra-de-proteccion' => 'insurance_purchase' ]; /** * DA — Rewrite url */ $system_routes["da"] = [ 'herre' => 'gender_mens', 'dame' => 'gender_womens', 'brands' => 'all_brands', 'promo' => 'products_promo', 'best-sellers' => 'best_sellers', 'nyheder' => 'products_featured', 'luksus' => 'products_luxury', 'register-som-et-selskab' => 'signup_business', 'saelge-med-kechiq' => 'sell_with_kechiq', 'blive-forhandler' => 'become_reseller', 'planer-og-satser' => 'plans_and_pricing', 'concept-boutique' => 'concept_boutique', 'concept-boutique-dubai' => 'concept_boutique_dubai', 'concept-boutique-milano' => 'concept_boutique_milano', 'tendens' => 'trend', 'gaveideer' => 'gift_ideas', // Info page 'hvem-vi-er' => 'about', 'privatliv' => 'privacy', 'betalingsmetoder' => 'payment_methods', 'forsendelser' => 'shipping', 'vender-tilbage' => 'returns', 'vilkar' => 'terms', 'indtryk' => 'impressum', 'hjaelp' => 'help', 'juridiske-meddelelser' => 'legal_notes', 'innovativ-opstart' => 'innovative_startup', 'kob-beskyttelse' => 'insurance_purchase', ]; /** * PL — Rewrite url */ $system_routes["pl"] = [ 'mezczyzni' => 'gender_mens', 'kobiety' => 'gender_womens', 'brands' => 'all_brands', 'promocja' => 'products_promo', 'bestsellery' => 'best_sellers', 'nowosci' => 'products_featured', 'luksusowe' => 'products_luxury', 'zarejestruj-sie-jako-firma' => 'signup_business', 'sprzedaj-z-kechiq' => 'sell_with_kechiq', 'zostac-sprzedawca' => 'become_reseller', 'plany-i-stawki' => 'plans_and_pricing', 'concept-boutique' => 'concept_boutique', 'concept-boutique-dubai' => 'concept_boutique_dubai', 'concept-boutique-milano' => 'concept_boutique_milano', 'tendencja' => 'trend', 'pomysly-na-prezent' => 'gift_ideas', // Info page 'kim-jestesmy' => 'about', 'prywatnosc' => 'privacy', 'metody-platnosci' => 'payment_methods', 'przesylki' => 'shipping', 'zwroty' => 'returns', 'semestry' => 'terms', 'odcisk' => 'impressum', 'wsparcie' => 'help', 'informacje-prawne' => 'legal_notes', 'innowacyjny-startup' => 'innovative_startup', 'ochrona-zakupu' => 'insurance_purchase' ]; /** * RO — Rewrite url */ $system_routes["ro"] = [ 'barbati' => 'gender_mens', 'femei' => 'gender_womens', 'brands' => 'all_brands', 'promotie' => 'products_promo', 'cele-mai-vandute' => 'best_sellers', 'noutati' => 'products_featured', 'luxos' => 'products_luxury', 'inregistrare-ca-o-o-companie' => 'signup_business', 'vinde-cu-kechiq' => 'sell_with_kechiq', 'deveniti-revanzator' => 'become_reseller', 'planuri-si-tarife' => 'plans_and_pricing', 'concept-boutique' => 'concept_boutique', 'concept-boutique-dubai' => 'concept_boutique_dubai', 'concept-boutique-milano' => 'concept_boutique_milano', 'tendinta' => 'trend', 'idei-de-cadouri' => 'gift_ideas', // Info page 'cine-suntem-noi' => 'about', 'confidentialitate' => 'privacy', 'metode-de-plata' => 'payment_methods', 'expedieri' => 'shipping', 'se-intoarce' => 'returns', 'termeni' => 'terms', 'impressum' => 'impressum', 'ajutor' => 'help', 'avizele-legale' => 'legal_notes', 'startup-inovator' => 'innovative_startup', 'cumpara-protectie' => 'insurance_purchase' ]; /** * SV — Rewrite url */ $system_routes["sv"] = [ 'herr' => 'gender_mens', 'dam' => 'gender_womens', 'brands' => 'all_brands', 'kampanj' => 'products_promo', 'bastsaljare' => 'best_sellers', 'nyheter' => 'products_featured', 'lyx' => 'products_luxury', 'registrera-sig-som-foretag' => 'signup_business', 'salja-med-kechiq' => 'sell_with_kechiq', 'bli-aterforsaljare' => 'become_reseller', 'planer-och-priser' => 'plans_and_pricing', 'concept-boutique' => 'concept_boutique', 'concept-boutique-dubai' => 'concept_boutique_dubai', 'concept-boutique-milano' => 'concept_boutique_milano', 'trend' => 'trend', 'present-ideer' => 'gift_ideas', // Info page 'vilka-vi-ar' => 'about', 'integritet' => 'privacy', 'betalningsmetoder' => 'payment_methods', 'forsandelser' => 'shipping', 'returnerar' => 'returns', 'villkor' => 'terms', 'intryck' => 'impressum', 'hjalp' => 'help', 'juridiska-meddelanden' => 'legal_notes', 'innovativ-startup' => 'innovative_startup', 'kopskydd' => 'insurance_purchase' ]; = $range); return $min + $rnd; } # Find url in text and make them link function linkURLFromString($text) { # Find url and make them link $reg_exUrl = '!(http|ftp|scp)(s)?:\/\/[a-zA-Z0-9.?&_/=]+!'; $reg_exUrl = '/\b(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)[-A-Z0-9+&@#\/%=~_|$?!:,.]*[A-Z0-9+&@#\/%=~_|$]/i'; // Check if there is a url in the text if(preg_match_all($reg_exUrl, $text, $url)) { for($i = 0; $i < count($url[0]); $i++) { $linkUrl = $url[0][$i]; if(strpos($text, "") === FALSE) { if(strpos($linkUrl, "http") === false) $linkUrl = "http://".$linkUrl; $text = str_replace($linkUrl, "".$linkUrl." ", $text); } } } return $text; } # Find first url in text and return function getURLFromString($text) { # Find url and make them link $reg_exUrl = '!(http|ftp|scp)(s)?:\/\/[a-zA-Z0-9.?&_/=]+!'; $reg_exUrl = '/\b(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)[-A-Z0-9+&@#\/%=~_|$?!:,.]*[A-Z0-9+&@#\/%=~_|$]/i'; // Check if there is a url in the text if(preg_match_all($reg_exUrl, $text, $url)) { for($i = 0; $i < count($url[0]); $i++) { $linkUrl = $url[0][$i]; if(strpos($text, "") === FALSE) return $linkUrl; } return false; }else return false; } function transformTextURLToHtmlLink($text) { $regex = '@((https?://)?([-\w]+\.[-\w\.]+)+\w(:\d+)?(/([-\w/_\.]*(\?\S+)?)?)*)@'; if(preg_match_all($regex, $text, $url)) { for($i = 0; $i < count($url[0]); $i++) { $linkText = $url[0][$i]; if(strpos($linkText, "http://") !== 0 AND strpos($linkText, "https://") !== 0 AND strpos($linkText, "ftp://") !== 0 AND strpos($linkText, "://") === false) $link = "http://".$linkText; else $link = $linkText; $text = str_replace($linkText, ''.$linkText.'', $text); } } return $text; } /** * Get random color */ function randomColor() { $colors = [ "#F29900", "#FCBF02", "#FEDE02", "#FB8D6B", "#FA6447", "#D94635", "#AD2B65", "#AD85E5", "#7C52CC", "#583699", "#6D8EF2", "#5EDDEB", "#802185", "#AC38B3", "#D87ED2", "#F25CA0", "#D8347E", "#6AA817", "#93CC2A", "#B9E04C", "#6DD962", "#52BF4D", "#40A343", "#1E8A55", "#29B368", "#45D694" ]; return $colors[rand(0, count($colors) -1)]; } /** * Get file size from kb * * Return readable size for file * * @param int $bytes * @param int $decimals * * @return string */ function getFileSizeFromKb($bytes, $decimals = 2) { $size = ['b','KB','MB','GB','TB','PB','EB','ZB','YB']; $factor = floor((strlen($bytes) - 1) / 3); return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$size[$factor]; } /** * Truncate string * * @param string $string * @param int $length * * @return string */ function truncate($string, $length) { if(strlen($string) > $length) { return substr($string, 0, $length)."..."; }else return $string; } /** * Format currency string * * @param float $val * * @return float */ /* function formatCurrency($val) { return number_format($val, 2, ",", "."); } */

'.$err_message.'

['.$err_line.'] '.$err_file.' '; } } $value) { if($key == "title") $link_title = addslashes($value); elseif($key == "description") $link_description = addslashes($value); elseif($key == "image") $link_image = $value; elseif($key == "video:url") { $link_video = $value; } } $urlFavicon = urlencode($link); $favicon = "https://www.google.com/s2/favicons?domain=".$urlFavicon; return [ "linkFull" => $linkFull, "link" => $link, "title" => $link_title, "description" => $link_description, "image" => $link_image, "video" => $link_video, "favicon" => $favicon ]; }else return false; } /** * Extract base domain from link * * @param string $link * @return string */ function extractDomainFromLink($link) { $domain = str_ireplace('www.', '', parse_url($link, PHP_URL_HOST)); return $domain; } /** * @param $link * @return false|string */ function get_extension($link) { return substr(strrchr($link, '.'), 1); } 0) { $list_files = array_merge($list_files, $list_files_sub); } }else { $ext = strtolower(substr($ff, strrpos($ff, ".")+1)); $size = filesize($dir."/".$ff); $list_files[] = array("realpath" => $dir."/".$ff, "filename" => $ff, "ext" => $ext, "filesize" => $size); } } } } return $list_files; } /** * Get all files from directory (and subdirectory recursive) ordered by created moment * * @param string $dir Start directory * * @return array */ function listFolderFilesByDate($dir){ $ignored = array('.', '..', '.svn', '.htaccess'); $files = array(); foreach (scandir($dir) as $file) { if (in_array($file, $ignored)) continue; $files[$file] = filemtime($dir . '/' . $file); } #arsort($files); $files = array_keys($files); return ($files) ? $files : false; } /** * Copy all files from a dir to another * * @param string $src * @param string $dst * * @return void */ function copyFilesFromDirToDir($src,$dst) { $dir = opendir($src); @mkdir($dst); while(false !== ( $file = readdir($dir)) ) { if (( $file != '.' ) && ( $file != '..' )) { if ( is_dir($src . '/' . $file) ) { copyFilesFromDirToDir($src . '/' . $file,$dst . '/' . $file); } else { copy($src . '/' . $file,$dst . '/' . $file); } } } closedir($dir); } /** * Remove dir and all related files * * @param string $dir * @return void */ function removeDirRecursive($dir) { foreach(scandir($dir) as $file) { if ('.' === $file || '..' === $file) continue; if (is_dir("$dir/$file")) removeDirRecursive("$dir/$file"); else unlink("$dir/$file"); } rmdir($dir); } $value) $filters[$column] = (is_string($value)) ? [$value, PDO::PARAM_STR] : $value; return array_values($filters); } setTitle($title); $push->setMessage($message); $push->setIsBackground(TRUE); $json_data = [ "reloadPath" => $reloadPath, "reloadId" => $reloadId, "notificationToken" => $notificationToken, "title" => $title, "body" => $message ]; # For all notifications settings see https://firebase.google.com/docs/cloud-messaging/http-server-ref#notification-payload-support $json_notification = [ "title" => $title, "body" => $message, "click_action" => $clickAction, "icon" => "fcm_push_icon.png", "color" => "#4F90E0", "sound" => "default" ]; $regId = isset($regId) ? $regId : ''; $response = $firebase->send($regId, $json_data, $json_notification); # Process response return (array) json_decode($response); } customer_set->is_allowed_to_show_tax) { case true: $row['price_margin'] = $row['price_not_taxed_eur'] - $row['purchase_price'] - $row['real_shipping_cost_eur']; break; default: $row['price_margin'] = $row['price_eur'] - $row['purchase_price'] - $row['real_shipping_cost_eur']; } if( $row['price_margin'] < 20 ) $row['margin_level'] = 'LOW'; else if ( $row['price_margin'] >= 20 AND $row['price_margin'] < 50 ) $row['margin_level'] = 'MED'; else if ( $row['price_margin'] >= 50 AND $row['price_margin'] < 100 ) $row['margin_level'] = 'HIGH'; else $row['margin_level'] = 'TOP'; } function parse_product_row_prices(&$row, $settings) { $row['purchase_price'] = (float) $row['purchase_price']; $row['purchase_price_not_taxed_eur'] = (float) $row['purchase_price']; $row['price_not_taxed'] = (float) $row['price']; $row['price_not_taxed_eur'] = (float) convertCurrency('EUR', $row['price_not_taxed'], $settings->currency); $row['price'] = (float) Product::parsePrice($row['price']); $row['tax'] = (float) ( tax_type($settings->country, ($settings->customer_set->type == 'B2B'))->product == 'included' ) ? round($row['price'] - ($row['price'] / 1.22), 2) : 0; $row['price_eur'] = (float) convertCurrency('EUR', $row['price'], $settings->currency); $row['origin_price'] = (float) Product::parseOriginPrice($row['origin_price']); $row['real_shipping_cost_eur'] = (float) CONFIG['available']['shipping']['real_costs_by_project_id'][$settings->project_id]; } function marketplace_parse_product_row_prices(&$row, $settings) { $roundOriginPrice = false; if ($row['price'] == $row['origin_price']) { $roundPrice = false; } else { $roundPrice = true; } $row['purchase_price'] = (float) $row['purchase_price']; $row['purchase_price_not_taxed_eur'] = (float) $row['purchase_price']; $row['price_not_taxed'] = (float) $row['price']; $row['price_not_taxed_eur'] = (float) convertCurrency('EUR', $row['price_not_taxed'], $settings->currency); $row['price'] = (float) Product::parsePrice($row['price'], $roundPrice); $row['tax'] = (float) ( tax_type($settings->country, ($settings->customer_set->type == 'B2B'))->product == 'included' ) ? round($row['price'] - ($row['price'] / 1.22), 2) : 0; $row['price_eur'] = (float) convertCurrency('EUR', $row['price'], $settings->currency); $row['origin_price'] = (float) Product::parseOriginPrice($row['origin_price'], $roundOriginPrice); $row['real_shipping_cost_eur'] = (float) CONFIG['available']['shipping']['real_costs_by_project_id'][$settings->project_id]; if ($row['price'] == $row['origin_price']) { $row['origin_price'] = round($row['origin_price']); $row['price'] = $row['origin_price']; } } function parse_product_row_images(&$row) { $row['images'] = []; if($row['path_images']) { $row['path_images'] = array_filter(explode(';', $row['path_images'])); foreach ($row['path_images'] as $path_image) { $row['images'][] = HOST_IMAGES . DIRECTORY_SEPARATOR . $path_image; } if( !empty($row['image_brand_box']) ) { $row['images'][] = HOST_IMAGES . DIRECTORY_SEPARATOR . $row['image_brand_box']; } } else { $row['images'][] = HOST_IMAGES . DIRECTORY_SEPARATOR . $row['path_default_image']; } if( isset($row['path_medium_primary_image']) ) { $row['link_medium_primary_image'] = HOST_IMAGES . DIRECTORY_SEPARATOR . $row['path_medium_primary_image']; } } function parse_custom_labels(&$row, $settings) { if($settings->custom_labels == []) { return null; } $row['custom_label_0'] = (in_array($row['id_anticipa'], $settings->custom_labels['stock'])) ? 'stock' : null; $row['custom_label_2'] = (in_array($row['id_anticipa'], $settings->custom_labels['new_product'])) ? 'new_product' : null; $row['custom_label_3'] = (in_array($row['id_anticipa'], $settings->custom_labels['selection'])) ? 'selection' : null; } function parse_product_row_attributes(&$row) { $row['attributes'] = []; foreach ( json_decode($row['encoded_attributes'], true) as $attribute) { foreach ($attribute as $key => &$value) { if( in_array($key, ['attribute_group_texts', 'attribute_group_code', 'attribute_texts']) ) { $value = hex2bin($value); } if( in_array($key, ['attribute_group_texts', 'attribute_texts']) ) { $value = json_decode($value, true); } } $row['attributes'][$attribute['attribute_group_code']] = $attribute; } } function parse_product_row_texts(&$row) { $row['texts'] = json_decode($row['texts'], true); } function parse_product_row_category_texts(&$row) { $row['category_texts'] = json_decode($row['category_texts'], true); } function google_merchant_all_shipping_methods($settings): array { $countryId = GeoCountry::getIdsByCodesCached([$settings->country])[0]; $taxType = tax_type($countryId); return [ 'STANDARD' => [ 'price' => Shipping::calcPrice( $settings->project_id, $countryId, 'STANDARD', false, 1, ($taxType->product == 'included') ), 'enabled' => Shipping::isEnabledMethod( $settings->project_id, $countryId, 'STANDARD', false ) ], 'EXPRESS' => [ 'price' => Shipping::calcPrice( $settings->project_id, $countryId, 'EXPRESS', false, 1, ($taxType->product == 'included') ), 'enabled' => Shipping::isEnabledMethod( $settings->project_id, $countryId, 'EXPRESS', false ) ], 'KFAST' => [ 'price' => Shipping::calcPrice( $settings->project_id, $countryId, 'KFAST', false, 1, ($taxType->product == 'included') ), 'enabled' => Shipping::isEnabledMethod( $settings->project_id, $countryId, 'KFAST', false ) ] ]; } function google_merchant_available_shipping_methods_on_item_api($settings, $shippingMethods, $item): array { $shipping = []; foreach ($shippingMethods as $shippingMethodCode => $shippingMethod) { if ($shippingMethodCode == 'KFAST') { $shippingMethod['enabled'] = ($shippingMethods['KFAST']['enabled'] AND CONFIG['settings']['shipping']['requirements']['kfast']['days_of_management'] >= $item['days_of_management']); } if ($shippingMethod['enabled']) { $shipping[] = [ 'price' => [ 'value' => $shippingMethod['price'], 'currency' => $settings->currency, ], 'country' => $settings->country, 'service' => strtolower($shippingMethodCode), 'weight' => null, 'unit' => null, ]; } } return $shipping; } function google_merchant_available_shipping_methods_on_item_xml($settings, $shippingMethods, $item): array { $shipping = []; foreach ($shippingMethods as $shippingMethodCode => $shippingMethod) { if ($shippingMethodCode == 'KFAST') { $shippingMethod['enabled'] = ($shippingMethods['KFAST']['enabled'] AND CONFIG['settings']['shipping']['requirements']['kfast']['days_of_management'] >= $item['days_of_management']); } if ($shippingMethod['enabled']) { $shipping[] = [ 'g:price' => $shippingMethod['price'], 'g:country' => $settings->currency, 'g:service' => strtolower($shippingMethodCode) ]; } } return $shipping; } } time(), "jti" => $jti, "iss" => HOST, "exp" => time() + $JWTExpireSeconds, "data" => $payloadData ]; return JWT::encode($payload, $JWTSecret); } /** * User is Logged * * Check if there's a session user active * * @return boolean */ function userIsLogged() { $isLogged = (new Auth)->getIsUserLogged(); if(is_array($isLogged) OR $isLogged === true) return true; else return false; } /** * Get Logged User * * Check if there's a session user active and return data * * @return array|boolean */ function userLogged() { $loggedUser = Auth::getLoggedUser(); if(is_array($loggedUser)) return $loggedUser; else if($loggedUser === true) return $_SESSION[SESSION_USER]; else return false; } /** * Return user lang code * @return string */ function getUserLang() { return ($_SESSION['lang']) ?: 'EN'; } /** * @param $password * @return false|string */ function user_password_hash($password) { return hash('sha256', trim($password)); } /** * @param $password * @param $hashedPassword * @return bool */ function user_password_verify($password, $hashedPassword) { return ( $hashedPassword === user_password_hash($password) ); } 0 AND $helperDateUnix <= $now) { $delay = $now - $helperDateUnix; if($delay == 0 OR $delay < 60) $delay = getDictionaryTerm("HELPER_DATE_NOW"); elseif($delay < 3600) { # Cur Hour $tmp = floor($delay / 60); $str = $tmp == 1 ? getDictionaryTerm("HELPER_DATE_ONE_MIN_AGO") : getDictionaryTerm("HELPER_DATE_MIN_AGO"); $delay = $tmp." ".$str; }elseif($delay < 86400) { # Cur day $tmp = floor($delay / 3660); $str = $tmp == 1 ? getDictionaryTerm("HELPER_DATE_ONE_HOUR_AGO") : getDictionaryTerm("HELPER_DATE_HOUR_AGO"); $delay = $tmp." ".$str; }elseif($delay < 604800) { # Cur week $tmp = floor($delay / 86400); $str = $tmp == 1 ? getDictionaryTerm("HELPER_DATE_ONE_DAY_AGO") : getDictionaryTerm("HELPER_DATE_DAY_AGO"); $delay = $tmp." ".$str; }elseif($delay < 2419200) { # Cur month $tmp = floor($delay / 604800); $str = $tmp == 1 ? getDictionaryTerm("HELPER_DATE_ONE_WEEK_AGO") : getDictionaryTerm("HELPER_DATE_WEEK_AGO"); $delay = $tmp." ".$str; }else $delay = $helperDateDay."/".$helperDateMonth."/".$helperDateYear; }elseif($helperDateUnix > 0 AND $helperDateUnix > $now) { $delay = $helperDateUnix - $now; if($delay == 0) $delay = getDictionaryTerm("HELPER_DATE_NOW"); elseif($delay < 3600) { # Cur Hour $tmp = floor($delay / 60); $delay = $tmp == 1 ? "fra un minuto" : "fra ".$tmp." minuti"; }elseif($delay < 86400) { # Cur day $tmp = floor($delay / 3660); $delay = $tmp == 1 ? "fra un'ora" : "fra ".$tmp." ore"; }elseif($delay < 604800) { # Cur week $tmp = floor($delay / 86400); $delay = $tmp == 1 ? "fra un giorno" : "fra ".$tmp." giorni"; }elseif($delay < 2419200) { # Cur month $tmp = floor($delay / 604800); $delay = $tmp == 1 ? "fra una settimana" : "fra ".$tmp." settimane"; }else $delay = $helperDateDay."/".$helperDateMonth."/".$helperDateYear; }else $delay = "-"; return $delay; } function now() { $now = new DateTime(); return $now->format("Y-m-d H:i:s"); } /** * From the departure date calculate the "delivery date" excluding saturdays and sundays and holidays * @param $dateOfShipment * @param $deliveryTimesInDays * @return string */ function calcDeliveryDate($dateOfShipment, $deliveryTimesInDays) { # Days (in number) where the couriers work $workingDays = [1, 2, 3, 4, 5]; # Days of Italian fixed holidays (you can also enter the year instead of the asterisk) $holidayDays = [ "*-01-01", # New Year "*-01-06", # Epiphany "*-04-25", # Anniversary of the Liberation "*-05-01", # Labour day "*-06-02", # Republic Day "*-08-15", # Mid-August "*-11-01", # All Saints "*-12-08", # Immaculate Conception "*-12-25", # Christmas "*-12-26", # Saint Stephen ]; try { $dateOfShipment = new DateTime($dateOfShipment); } catch (Exception $e) { echo $e; } while ($deliveryTimesInDays) { $dateOfShipment->modify("+1 day"); if (!in_array($dateOfShipment->format("N"), $workingDays)) continue; if (in_array($dateOfShipment->format("Y-m-d"), $holidayDays)) continue; if (in_array($dateOfShipment->format("*-m-d"), $holidayDays)) continue; $deliveryDate = $dateOfShipment->format("Y-m-d"); $deliveryTimesInDays--; } return $deliveryDate; } $idPage], headersApiAnticipa, false, true, false); if($response["status"] == 200) { return $response["response"]["params"]; } return []; } /** * Get Files for directory * * @param int $idDirectory * * @return array */ function anticipaGetDirectoryFiles($idDirectory) { $response = curlRequest(domainAnticipa."/API/file/getForDirectory", ["id" => $idDirectory], headersApiAnticipa, false, true, false); if($response["status"] == 200) { return $response["response"]["params"]; } return []; } /** * Get positions for recruiting * * @return array */ function anticipaGetRecruitingPositions() { if(!isset($_SESSION["ANTICIPA_RECRUITING_POSITIONS"]) OR isset($_GET["f"])) { $response = curlRequest(domainAnticipa . "/API/recruitingPosition/listAll", [], headersApiAnticipa, false, true, false); if ($response["status"] == 200) { $_SESSION["ANTICIPA_RECRUITING_POSITIONS"] = $response["response"]["params"]; return $response["response"]["params"]; } }else return $_SESSION["ANTICIPA_RECRUITING_POSITIONS"]; return []; } /** * Get positions count for recruiting * * @return array */ function anticipaGetRecruitingPositionsCount($filters = []) { if(!isset($_SESSION["ANTICIPA_RECRUITING_POSITIONS_COUNT"]) OR isset($_GET["f"])) { $response = curlRequest(domainAnticipa . "/API/recruitingPosition/countAll", $filters, headersApiAnticipa, false, true, false); if ($response["status"] == 200) { $_SESSION["ANTICIPA_RECRUITING_POSITIONS_COUNT"] = $response["response"]["params"]; return $response["response"]["params"]; } }else return $_SESSION["ANTICIPA_RECRUITING_POSITIONS_COUNT"]; return []; } /** * Apply for recruiting position * * @param array $application * * @return array */ function anticipaApplyForRecruitingPosition($application) { $response = curlRequest(domainAnticipa."/API/recruitingApplicant/apply", $application, headersApiAnticipa, false, true, false); if($response["status"] == 200) { return $response["response"]["params"]; } return false; } /** * Newsletter subscribtion * * @param array $application * * @return array */ function anticipaSubscribeNewsletter($application) { $response = curlRequest(domainAnticipa."/API/newsletterUser/insert", $application, headersApiAnticipa, false, true, false); if($response["status"] == 200) { return $response["response"]["params"]; } return false; } /** * Get articles for lang * * @return array */ function anticipaGetBlogArticlesForLang() { if(!isset($_SESSION["ANTICIPA_BLOG_ARTICLES"]) OR isset($_GET["f"])) { $filters = ["lang" => $_SESSION["lang"], "id_project" => anticipaProject]; if(isset($_GET["draft"])) $filters["draft"] = 1; $response = curlRequest(domainAnticipa . "/API/blogArticle/findForLang", $filters, headersApiAnticipa, false, true, false); if ($response["status"] == 200) { $_SESSION["ANTICIPA_BLOG_ARTICLES"] = $response["response"]["params"]; return $response["response"]["params"]; } }else return $_SESSION["ANTICIPA_BLOG_ARTICLES"]; return []; } /** * Check Coupon * * @param string $code * @param string $customerEmail * * @return array */ function anticipaCheckCoupon($code, $customerEmail = '') { $filters = ["code" => $code, "id_project" => anticipaProject, "customer_email" => $customerEmail]; $response = curlRequest(domainAnticipa . "/API/articleCoupon/check", $filters, headersApiAnticipa, false, true, false); if ($response["status"] == 200) { return $response["response"]["params"]; } return []; } 0) { $value = floor($value) + 1; } return (float) $value; } function roundOriginPrice($value): float { # Remove decimals $value = round($value); # Convert float to string $value = (string) $value; $last = (int) substr($value, -1); # Convert string to float $value = (float) $value; if($last > 0) { if($last < 5) { $value += 5 - $last; } else if ($last > 5) { $value += 10 - $last; } } return (float) $value; } } [ 'amount' => (string) $purchase->amount, 'email' => (string) $purchase->user->email, 'billingAddress' => [ 'givenName' => (string) $purchase->addresses->billing->firstname, 'surname' => (string) $purchase->addresses->billing->lastname, 'phoneNumber' => (string) $purchase->addresses->billing->phone, 'streetAddress' => (string) $purchase->addresses->billing->address, 'locality' => (string) $purchase->addresses->billing->city, 'postalCode' => (string) $purchase->addresses->billing->zip, 'countryCodeAlpha2' => (string) $purchase->addresses->billing->country, ] ] ]; } function create($purchaseId, $language, $elementId): array { $project_id = User::getProjectId(); $purchase = Purchase::get($purchaseId); $clientToken = (new Braintree)->getClientToken($purchase->currency); $params = [ 'authorization' => (string) $clientToken, 'container' => (string) '#' . $elementId, 'threeDSecure' => true, 'locale' => (isset(CONFIG['available']['payments']['braintree_locale_by_language'][$language])) ? CONFIG['available']['payments']['braintree_locale_by_language'][$language] : 'en_EN', ]; if( in_array('PAYPAL', BRAINTREE_PAYMENTS_METHODS) AND in_array('PAYPAL', CONFIG['available']['payments']['braintree_enabled_methods_by_projects_ids'][$project_id]) ) { $params = array_merge($params, calc_PaymentMethod_PayPal()); } if( in_array('APPLE_PAY', BRAINTREE_PAYMENTS_METHODS) AND in_array('APPLE_PAY', CONFIG['available']['payments']['braintree_enabled_methods_by_projects_ids'][$project_id]) ) { $params = array_merge($params, calc_PaymentMethod_ApplePay($purchase->amount)); } if( in_array('GOOGLE_PAY', BRAINTREE_PAYMENTS_METHODS) AND in_array('GOOGLE_PAY', CONFIG['available']['payments']['braintree_enabled_methods_by_projects_ids'][$project_id]) ) { $params = array_merge($params, calc_PaymentMethod_GooglePay($purchase->amount, $purchase->currency)); } return $params; } function calc_PaymentMethod_PayPal(): array { return [ 'paypal' => [ 'flow' => 'vault', 'buttonStyle' => [ 'color' => 'blue', 'shape' => 'rect', 'size' => 'large' ] ] ]; } function calc_PaymentMethod_ApplePay($amount): array { return [ 'applePay' => [ 'displayName' => (string) BRAINTREE_MERCHANT_DISPLAY_NAME, 'paymentRequest' => [ 'total' => [ 'label' => (string) BRAINTREE_MERCHANT_DISPLAY_NAME, 'amount' => (string) $amount, ], 'requiredBillingContactFields' => [ 'postalAddress' ] ] ] ]; } function calc_PaymentMethod_GooglePay($amount, $currency): array { return [ 'googlePay' => [ 'googlePayVersion' => 2, 'merchantId' => BRAINTREE_GOOGLE_PAY_MERCHANT_ID, 'transactionInfo' => [ 'totalPriceStatus' => 'FINAL', 'totalPrice' => (string) $amount, 'currencyCode' => (string) $currency, ], 'allowedPaymentMethods' => [ [ 'type' => 'CARD', 'parameters' => [ 'billingAddressRequired' => false, 'billingAddressParameters' => [ 'format' => 'FULL' ] ] ] ] ] ]; } } $routes) { foreach($routes AS $label => $value) { if($label == $controller) { $controller = $value; } if($label == $method AND !$matched) { $matched = true; $matched_language = $lang; $method = $value; } } } } if(is_null($controller) AND !is_null($matched_language)) { $hrefs = []; foreach (CONFIG['available']['languages'] as $language) { $hrefs[strtolower($language)] = array_search($method, $system_routes[strtolower($language)]); } \view_params\Route\hreflangs($hrefs); $ref_language = helpers\lang_dir\ref_language($matched_language); $translated_route = array_search($method, $system_routes[$ref_language]); $translatable = (count( array_filter($system_routes, function($route) use ($translated_route) { return isset($route[$translated_route]); }) ) == 1); if($translatable) { helpers\lang_dir\route( $translated_route, $matched_language ); } else { helpers\lang_dir\check(301); } } else { $hrefs = []; foreach (CONFIG['available']['languages'] as $language) { $hrefs[strtolower($language)] = RAW_PATH; } \view_params\Route\hreflangs($hrefs); } } format($format) == $date; } /** * Check valid URL * * @param $url * * @return bool */ function isUrl($url) { if(filter_var($url, FILTER_VALIDATE_URL)) return true; else return false; } /** * Check string is JSON format * * @param $string * @return bool|mixed */ function isJson($string) { if(is_numeric($string)) return false; json_decode($string); return (json_last_error() == JSON_ERROR_NONE) ? true : false; } /** * Check if var is array or json * @param $var * @param bool $returnItem * @return array|bool */ function isArrayOrJson($var, $returnItem = false) { if(is_array($var)) return ($returnItem) ? $var : true; else if(isJson($var)) return ($returnItem) ? json_decode($var, true) : true; else return false; } /** * Check if string is valid for url slug * @param $string * @return false|int */ function isSlug($string) { return preg_match('/^[a-z0-9]+(-?[a-z0-9]+)*$/i', $string); } /** * Check if the value is integer, regardless of the type of value * * @param $var * @return bool */ function isInt($var) { return (filter_var($var, FILTER_VALIDATE_INT) === 0 || filter_var($var, FILTER_VALIDATE_INT)) ? true : false; } /** * Check if the value is boolean * @param $var * @return bool */ function isBool($var) { return (filter_var($var, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) !== NULL) ? true : false; } 0) { if($isMultilevel){ curlBuildMultilevelData($params, $newParams); $postData = (array) $newParams; }else { #$postDataJSON = json_encode($postData); $postData = (array) $params; } }elseif($params AND strlen($params) > 0){ # Could be JSON string $postData = $params; }else $postData = false; curl_setopt ( $ch, CURLOPT_URL, $endpoint ); curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 ); if($isPost){ curl_setopt ( $ch, CURLOPT_POST, true ); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); } if(is_array($headers) AND count($headers) > 0) curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers); $output = curl_exec ( $ch ); $info = curl_getinfo ( $ch ); curl_close ( $ch ); if($debug) var_dump($output); # Convert output params in array $response = json_decode($output, true); if( $die_on_fails AND !in_array(intval($info['http_code']), [200,201]) ) { echo 'Server processing problem.'; die(); } return [ "status" => $info["http_code"], "response" => $response ]; } /** * CURL Request (cached) * Create CURL Request, send params and get response status and message * * @param $duration * @param $endpoint * @param $params * @param $headers * @param false $isMultilevel * @param bool $isPost * @param false $debug * @param false $die_on_fails * @return mixed|null */ function curlRequestCached($duration, $endpoint, $params, $headers, $isMultilevel = false, $isPost = true, $debug = false, $die_on_fails = false) { return Cache::store([ 'duration' => $duration, ], 'curlRequest', $endpoint, $params, $headers, $isMultilevel, $isPost, $debug, $die_on_fails); } /** * Format multilevel params for CURL request (associative array) * * @param array $params * @param array $newParams * @param string $prefix * */ function curlBuildMultilevelData($params, &$newParams = array(), $prefix = null) { if ( is_object( $params ) ) { $params = get_object_vars( $params ); } foreach ( $params AS $key => $value ) { $k = isset( $prefix ) ? $prefix . '[' . $key . ']' : $key; if ( is_array( $value ) OR is_object( $value ) ) { curlBuildMultilevelData( $value, $newParams, $k ); } else { $newParams[$k] = $value; } } } 0.5) { $value += 1 - $decimals; } else if ($decimals < 0.5) { $value = $value - $decimals; } return (float) $value; } } tableName = "user"; } /** * @param $item * @return bool */ public function parentUpdate($item) { return parent::update($item); } /** * Signup * * @param $item * @return array|string */ public function signup($item) { if(UserValidate::signup($item)) { if(( !boolval($item['is_active']) AND !$item['is_b2b']) OR UserValidate::emailIsUniqueForActiveUsers($item['email'])) { if( $item['is_b2b'] ) { $item['is_active'] = false; } $id = parent::insert([ 'uuid' => Uuid::uuid4()->toString(), 'id_customer_set' => CONFIG['defaults']['id_customer_set'][ ($item['is_b2b']) ? 'b2b' : 'b2c' ], 'firstname' => ucwords($item['firstname']), 'lastname' => ucwords($item['lastname']), 'email' => strtolower($item['email']), 'password' => ($item['is_active'] OR $item['is_b2b']) ? user_password_hash($item['password']) : null, 'language' => strtoupper($item['language']), 'signup_domain' => User::getDomain(), 'is_b2b' => boolval($item['is_b2b']), 'has_newsletter' => boolval($item['has_newsletter']), 'is_active' => boolval($item['is_active']), 'billing_company' => ($item['is_b2b']) ? $item['billing_company'] : null, 'billing_vat' => ($item['is_b2b']) ? $item['billing_vat'] : null, 'billing_fiscal_code' => ($item['is_b2b']) ? $item['billing_fiscal_code'] : null, 'billing_pec' => ($item['is_b2b']) ? $item['billing_pec'] : null, 'billing_sdi' => ($item['is_b2b']) ? $item['billing_sdi'] : null, 'json_business_additional_info' => ($item['is_b2b']) ? json_encode($item['business_additional_info']) : null, 'moment' => now(), 'last_update' => now(), ]); if(is_numeric($id)) { $user = $this->get($id, 'all'); if($item['is_active'] AND !$item['is_b2b']) { # Login Auth::login($item['email'], $item['password'], $user, true); # Sync accounts if($this->syncAccountsIdsAvailable($user['email'])) { $user['sync_accounts_token'] = $this->syncAccountCreateAndSaveToken($id, true, true); $user['tmp']['sync_accounts_is_available'] = true; } else { $user['tmp']['sync_accounts_is_available'] = false; } # Event UserEvent::signup($user); } else if ($item['is_b2b']) { foreach ($item['addresses'] as $address) { $addressId = (new UserAddress)->insert(array_merge($address, [ 'id_user' => $id, 'email' => $item['email'] ])); (new UserAddress)->setDefaultBilling($addressId, $id); } } if( $item['is_active'] AND $item['has_newsletter'] ) { Queue::create('User::signup/subscribe', ['body' => [ 'user' => [ 'id' => $id, 'email' => $item['email'], ], 'profiling' => [ 'LANGUAGE' => $item['language'], 'DOMAIN' => $item['signup_domain'], 'IS_BUSINESS' => boolval($item['is_b2b']), ] ]], '(new \libs\Mailchimp)->subscribe($body);'); } return $user; } else return L('HTTP_INTERNAL_SERVER_ERROR'); } else return L('USER_SIGNUP_EMAIL_CONFLICT'); } else return L('HTTP_STATUS_BAD_REQUEST'); } /** * Update * * @param array $item * @return bool|string */ public function update($item) { $validate = UserValidate::update($item); if($validate === true) { parent::update([ 'id' => $item['id'], 'firstname' => $item['firstname'], 'lastname' => $item['lastname'], 'email' => strtolower($item['email']), 'language' => strtoupper($item['language']), //'is_b2b' => boolval($item['is_b2b']), 'has_newsletter' => boolval($item['has_newsletter']), 'is_active' => boolval($item['is_active']), 'last_update' => now() ]); # User $user = $this->get($item['id'], 'all'); # Refresh Auth::refresh($user, $user['email']); # Event UserEvent::update(['user' => $user]); return true; } else return (is_string($validate)) ? $validate : L('HTTP_STATUS_BAD_REQUEST'); } /** * Login * * @param $item * @return array|string */ public function login($item) { if(UserValidate::login($item)) { $user = $this->findActiveUserByEmail($item['email']); if($user) { if( user_password_verify($item['password'], $user['password']) ) { $this->loadDependencies($user, true); # Login Auth::login($item['email'], $item['password'], $user, boolval($item['remember'])); return $user; } else return L("USER_LOGIN_PASSWORD_INVALID"); } else { $is_business_disabled = parent::findOne(['email' => $item['email'], 'is_b2b' => 1, 'is_active' => 0]); return ($is_business_disabled) ? L("USER_LOGIN_PENDING_ACTIVATION") : L("USER_LOGIN_EMAIL_NOT_FOUND"); } } else return L('HTTP_STATUS_BAD_REQUEST'); } /** * Change password by sending the current password and the new password with the relative confirmation * * @param $item * @return bool|string */ public function changePassword($item) { if(UserValidate::changePassword($item)) { $user = $this->get($item['id'], ['password']); if( user_password_verify($item['current_password'], $user['password']) ) { parent::update([ 'id' => $user['id'], 'password' => user_password_hash($item['new_password']), 'last_update' => now() ]); UserEvent::changePassword($user); return true; } else return L('USER_CHANGE_PASSWORD_DONT_MATCH'); } else return L('HTTP_STATUS_BAD_REQUEST'); } /** * Logout * * @return bool */ public function logout() { Auth::logout(); return true; } /** * Generate the token to reset the password, the token will have to be used with recoverPassword function * * @param $item * @return bool|string */ public function recoverPasswordRequest($item) { if(UserValidate::recoverPasswordRequest($item)) { $user = $this->findActiveUserByEmail($item['email']); if($user) { $token = Uuid::uuid4()->toString(); parent::update([ 'id' => $user['id'], 'password_recover_token' => $token ]); # Event UserEvent::recoverPasswordRequest($user, $token); return true; } else return L("USER_LOGIN_EMAIL_NOT_FOUND"); } else return L('HTTP_STATUS_BAD_REQUEST'); } /** * Get by password recover token * * @param $token * @return array|bool|mixed|string */ public function getByPasswordRecoverToken($token) { if(!empty($token)) return parent::findOne(['password_recover_token' => $token, 'is_active' => '1']); else return L('HTTP_STATUS_BAD_REQUEST'); } /** * Through the recovery token the user can now reset the password * * @param $item * @return bool|string */ public function recoverPassword($item) { if(UserValidate::recoverPassword($item)) { $user = parent::findOne(['password_recover_token' => $item['token'], 'is_active' => 1]); if($user['id'] > 0) { parent::update([ 'id' => $user['id'], 'password' => user_password_hash($item['new_password']), 'password_recover_token' => null, 'last_update' => now() ]); # Event UserEvent::recoverPassword($user); return true; } else return L("HTTP_STATUS_NOT_FOUND"); } else return L('HTTP_STATUS_BAD_REQUEST'); } /** * Update newsletter subscribe * * @param $item * @return bool|mixed|string */ public function updateNewsletterSubscription($item) { if(UserValidate::updateNewsletterSubscription($item)) { parent::update([ 'id' => $item['id'], 'has_newsletter' => boolval($item['has_newsletter']), 'last_update' => now() ]); # Event UserEvent::subscriptionNewsletterManager(['user' => $this->get($item['id'], 'all')]); return true; } else return L('HTTP_STATUS_BAD_REQUEST'); } /** * Find active user by email * * @param $email * @return array|bool */ public function findActiveUserByEmail($email) { return parent::findOne(['email' => $email, 'is_active' => 1]); } /** * Get item details * * @param int $id * @param string|array $dependencies * * @return array Complete item information */ public function get($id, $dependencies = false) { $item = parent::get($id); if($item) $this->loadDependencies($item, $dependencies); return $item; } /** * Init config */ public static function initConfig() { self::getConfig(); } /** * Return session config * * @return array */ public static function getConfig() { $_SESSION[SESSION_CONFIG]['id_project'] = self::getProjectId(); $_SESSION[SESSION_CONFIG]['domain'] = self::getDomain(); $_SESSION[SESSION_CONFIG]['id_customer_set'] = self::getCustomerSetId(); $_SESSION[SESSION_CONFIG]['is_b2b'] = self::isBusiness(); $_SESSION[SESSION_CONFIG]['currency'] = self::getCurrency(); $_SESSION[SESSION_CONFIG]['tax_type'] = tax_type(self::getCountry(), $_SESSION[SESSION_CONFIG]['is_b2b']); return $_SESSION[SESSION_CONFIG]; } /** * Return session user id * @return int */ public static function getId(): ?int { return (self::isLogged()) ? (int) $_SESSION[SESSION_USER]['id'] : null; } /** * Return session user email * @return int */ public static function getEmail() { return (self::isLogged()) ? (string) $_SESSION[SESSION_USER]['email'] : null; } /** * Return session config currency * * @return string */ public static function getCurrency() { return $_SESSION[SESSION_CONFIG]['currency']; } /** * Set session config currency * * @param $currency * @return string */ public static function setCurrency($currency) { $_SESSION[SESSION_CONFIG]['currency'] = $currency; } /** * Return session config country * * @return string */ public static function getCountry() { return $_SESSION[SESSION_CONFIG]['country']; } /** * Return country id * * @return int */ public static function getCountryId(): int { return (int) (new GeoCountry)->findOneCached([ 'code' => self::getCountry() ])['id']; } /** * Set session config country * * @param $country * @return string */ public static function setCountry($country) { $_SESSION[SESSION_CONFIG]['country'] = $country; } /** * Return session config language * * @param null $userId * @return string */ public static function getLanguage($userId = null) { $language = (is_numeric($userId)) ? instanceDao('user')->getLanguage($userId) : $_SESSION[SESSION_CONFIG]['language']; return ( DefaultValidate::isAvailableLanguage($language) ) ? $language : strtoupper(CONFIG['defaults']['language']); } /** * Set session config language * * @param $language * @return string */ public static function setLanguage($language) { Carbon::setLocale($language); $_SESSION[SESSION_CONFIG]['language'] = $language; } /** * Return session config language * * @return string */ public static function getLanguageLower() { return strtolower(self::getLanguage()); } /** * Return current domain * @return string */ public static function getDomain(): string { if( in_array(ENVIROMENT, ['staging', 'development']) AND isset($_SESSION[SESSION_CONFIG]['domain']) ) { return $_SESSION[SESSION_CONFIG]['domain']; } else { return (in_array(DOMAIN, CONFIG['available']['domains'])) ? DOMAIN : 'com'; } } /** * @return string */ public static function getDomainLanguage(): string { $domain = self::getDomain(); if(isset(CONFIG['available']['languages_by_domains'][$domain])) { return CONFIG['available']['languages_by_domains'][$domain]; } else { return CONFIG['defaults']['language']; } } /** * @return string */ public static function getDomainLanguageLower(): string { return strtolower(self::getDomainLanguage()); } /** * Return packageId * * @return int|null */ public static function getPackageId() { return (self::isLogged() AND self::isBusiness()) ? (int) (new static)->getPackageIdByUserId(self::getId()) : null; } /** * Return package permissions * * @return array|null */ public static function getPermissions() { return (self::getPackageId()) ? (array) Package::getPermissions(self::getPackageId()) : CONFIG['settings']['user']['permissions']['b2c']; } /** * @return mixed */ public static function getPermissionsCached() { return Cache::store([ 'key' => [self::getId(), self::isBusiness()], ], [User::class, 'getPermissions']); } /** * Check if user is allowed to dropshipping * * @return bool */ public static function isAllowedDropshipping(): bool { return ( self::isLogged() AND self::isBusiness() AND ( self::getPermissions()['dropshipping_national'] OR self::getPermissions()['dropshipping_europe'] ) ); } /** * Update language * * @param $language * @return bool */ public function updateLanguage($language) { $language = (DefaultValidate::isAvailableLanguage($language)) ? $language : find_language(); session_set_config([ 'language' => $language ]); if ( self::isLogged() ) { parent::update(['id' => User::getId(), 'language' => $language]); Carbon::setLocale(strtolower($language)); Auth::refresh( (new User)->get(User::getId(), 'all'), null, null, false); } return true; } /** * Return project id * @return int */ public static function getProjectId(): int { if( !\helpers\cache\is_request() ) { return (int) CONFIG['available']['projects_ids_by_domains'][self::getDomain()]; } else { return (int) $_SESSION[SESSION_CONFIG]['id_project']; } } /** * Get customer set id * * @return int|null */ public static function getCustomerSetId(): ?int { if( !\helpers\cache\is_request() ) { if(self::isLogged()) { $userId = self::getId(); $key = Cache::createKey( self::class . '>'. __FUNCTION__, get_defined_vars(), ['id_user' => $userId]); if( Cache::isCached($key) ) { return Cache::getCache($key); } else { $default = CONFIG['defaults']['id_customer_set'][ (self::isBusiness()) ? 'b2b' : 'b2c' ]; $idCustomerSet = ($userId) ? (new User)->get($userId)['id_customer_set'] : $default; $idCustomerSet = (DefaultValidate::id($idCustomerSet)) ? $idCustomerSet : $default; return (int) Cache::setCache($key, $idCustomerSet, Cache::MINUTES_15); } } else { return (int) CONFIG['defaults']['id_customer_set']['b2c']; } } else { return (int) $_SESSION[SESSION_CONFIG]['id_customer_set']; } } /** * isBusiness * * @return bool */ public static function isBusiness($userId = null): bool { if( is_null($userId) ) { if( !\helpers\cache\is_request() ) { if( self::isLogged() ) { $key = Cache::createKey( self::class . '>'. __FUNCTION__, get_defined_vars(), User::getId()); if( Cache::isCached($key) ) { return (bool) Cache::getCache($key); } else { return (bool) Cache::setCache($key, instanceDao('user')->isBusiness(self::getId()), Cache::MINUTES_15); } } else { return false; } } else { return (bool) $_SESSION[SESSION_CONFIG]['is_b2b']; } } else if (is_numeric($userId)) { return (bool) instanceDao('user')->isBusiness($userId); } else { return false; } } /** * hasDeferredBankTransfer * * @return bool */ public static function hasDeferredBankTransfer(): bool { return (bool) ((self::isLogged()) ? instanceDao('user')->hasDeferredBankTransfer(self::getId()) : false); } /** * Is logged * * @return bool */ public static function isLogged(): bool { return (bool) userIsLogged(); } /** * Session token * * @return mixed */ public static function getSessionToken() { return ($_SESSION['nav_token']) ?: null; } /** * Return package id of user * * @param $id * @return int */ public function getPackageIdByUserId($id) { return (int) instanceDao($this->tableName)->getPackageIdByUserId($id); } /** * Returns geo coutnry id dropshipping national * * @param $id * @return int */ public function getGeoCountryIdDropshippingNational($id) { return (int) parent::findOne(['id' => $id])['id_geo_country_dropshipping_national']; } /** * Return user is business * * @param $id * @return bool */ public function isBusinessByUserId($id) { return (bool) parent::findOne(['id' => $id])['is_b2b']; } /** * Returns allowed dropshipping countries ids * * @param $id * @return array */ public function getAllowedDropshippingCountriesIds($id): array { if( $this->isBusinessByUserId($id) ) { $packageId = $this->getPackageIdByUserId($id); $geoCountryIdDropshippingNational = $this->getGeoCountryIdDropshippingNational($id); $packagePermissions = Package::getPermissions($packageId); $countriesIds = []; if( $packagePermissions['dropshipping_europe'] ) { $countriesIds = array_merge($countriesIds, GeoCountry::getIdsByCodesCached(CONFIG['settings']['shipping']['dropshipping']['european_countries_codes'])); } if( $packagePermissions['dropshipping_national'] AND $geoCountryIdDropshippingNational ) { $countriesIds = array_merge($countriesIds, [$geoCountryIdDropshippingNational]); } return array_unique( \helpers\validate\array_int($countriesIds) ); } else { return []; } } /** * Check if user is allowed to dropshipping * * @param $id * @return bool */ public function isAllowedDropshippingByUserId($id): bool { if( $this->isBusinessByUserId($id) ) { $packageId = $this->getPackageIdByUserId($id); $packagePermissions = Package::getPermissions($packageId); return ( $packagePermissions['dropshipping_national'] OR $packagePermissions['dropshipping_europe'] ); } else { return false; } } /** * Check if countryId is allowed to dropshipping for user * * @param $id * @param $countryId * @return bool */ public static function isAllowedToDropshippingInCountry($id, $countryId): bool { return ( in_array($countryId, (new static)->getAllowedDropshippingCountriesIds($id)) ); } /** * Returns checkout min purchase * * @return float */ public static function getCheckoutMinPurchase(): float { return (float) json_decode((new static)->get(self::getId())['json_min_purchase'], true)[self::getCurrency()]; } /** * Merge unactive accounts with current active account * * @param $id * @param $token * @return bool|mixed|string */ public function syncAccounts($id, $token) { if(is_numeric($id) AND !empty($token)) { $user = parent::findOne(['id' => $id, 'sync_accounts_token' => $token]); if($user['id'] == $id) { $users_ids = $this->syncAccountsIdsAvailable($user['email']); foreach ($users_ids as $user_id) { # Addresses $addresses = UserAddress::___find(['id_user' => $user_id]); foreach ($addresses as $address) { UserAddress::___update(['id' => $address['id'], 'id_user' => $id]); } # Purchases $purchases = OrderDetail::___find(['id_user' => $user_id]); foreach ($purchases as $purchase) { OrderDetail::___update(['id' => $purchase['id'], 'id_user' => $id]); } } parent::update([ 'id' => $id, 'sync_accounts_token' => null, 'last_update' => now() ]); return true; } else return L('HTTP_STATUS_NOT_FOUND'); } else return L('HTTP_STATUS_BAD_REQUEST'); } /** * Sync acccount create and store token * * @param $id * @param false $ignore_validation * @param false $return_token * @return bool|mixed|string */ public function syncAccountCreateAndSaveToken($id, $ignore_validation = false, $return_token = false) { if($ignore_validation OR UserValidate::exist($id)) { $token = Uuid::uuid4()->toString(); parent::update([ 'id' => $id, 'sync_accounts_token' => $token, 'last_update' => now(), ]); return ($return_token) ? $token : true; } else return L('HTTP_STATUS_NOT_FOUND'); } /** * Returns not active users ids match by email * @param $email * @return array|false */ public function syncAccountsIdsAvailable($email) { if(isEmail($email)) { $ids = array_column(parent::find(['email' => $email, 'is_active' => '0']), 'id'); return (count($ids) > 0) ? $ids : false; } else return false; } /** * Returns some columns * * @param $id * @return mixed */ public static function display($id, $email = false) { $item = instanceDao('user')->display($id, $email); $item['fullname'] = sprintf('%s %s', $item['firstname'], $item['lastname']); $item['initials'] = getInitials($item['firstname'], $item['lastname']); return $item; } /** * Returns billing info * * @param $id * @return array */ public static function getBilling($id): array { $list = (array) instanceDao('user')->getBilling($id); foreach ($list as $columnName => $columnValue) { unset($list[$columnName]); $list[ str_replace('billing_', '', $columnName) ] = $columnValue; } return $list; } /** * isActive * @return bool */ public static function isActive(): bool { if( self::isLogged() ) { $key = Cache::createKey( self::class . '>'. __FUNCTION__, get_defined_vars(), User::getId()); if( Cache::isCached($key) ) { return (bool) Cache::getCache($key); } else { return (bool) Cache::setCache($key, instanceDao('user')->isActive(self::getId()), Cache::MINUTES_15); } } else { return false; } } /** * @param $email * @return int */ public static function getIdByEmail($email): int { return (int) instanceDao('user')->getIdByEmail($email); } /** * @param $id * @return bool */ public static function hasNewsletter($id = null): bool { return (bool) instanceDao('user')->hasNewsletter( $id ?? self::getId() ); } /** * @param null $id * @return bool */ public static function hasSettledCSV($id = null): bool { $id = (is_numeric($id)) ? $id : self::getId(); return (bool) instanceDao('user')->hasSettledCSV($id); } /** * @param null $id * @return bool */ public static function hasPackage($id = null): bool { $id = (is_numeric($id)) ? $id : self::getId(); return (bool) instanceDao('user')->hasPackage($id); } /** * @param null $id * @return false|string */ public static function getListingCSVPath($id = null) { $id = (is_numeric($id)) ? $id : self::getId(); if( self::isBusiness($id) AND self::hasSettledCSV($id) AND self::hasPackage($id) ) { $user = parent::___get($id); $package = Package::___get($user['id_package']); return sprintf('%s/listing/%s-%s-%s-%s.csv', DIR_PRIVATE, $user['csv_type'], $user['id_customer_set'], $package['type'], $package['code']); } else { return false; } } /** * @return false|mixed */ public static function getBoutique() { $key = array_search(self::getCountry(), array_column(CONFIG['available']['boutiques'], 'country')); if($key !== false) return CONFIG['available']['boutiques'][$key]; else return false; } /** * @param $vatNumber * @param null $countryCode * @return bool */ public function checkIfBillingVatByViesIsValid($vatNumber, $countryCode = null, $id = null): bool { $hash = md5(json_encode([$vatNumber, $countryCode])); $ignore = false; if (is_numeric($id)) { $user = parent::get($id); if($user['billing_vat_vies_hash'] == $hash) $ignore = true; } if (!$ignore) { $vatNumber = preg_replace('/\s+/', '', $vatNumber); $countryCodeDerived = substr($vatNumber, 0, 2); if (ctype_alpha($countryCodeDerived)) $vatNumber = substr($vatNumber, 2); else $countryCodeDerived = null; $valid = false; if (!$valid AND $countryCodeDerived) $valid = self::checkIfBillingVatByViesIsValidRequest($countryCodeDerived, $vatNumber); if (!$valid AND $countryCode) $valid = self::checkIfBillingVatByViesIsValidRequest($countryCode, $vatNumber); if (is_numeric($id)) { parent::update([ 'id' => $id, 'billing_vat_vies_valid' => $valid, 'billing_vat_vies_hash' => $hash, 'billing_vat_vies_checked_at' => now(), 'last_update' => now(), ]); } } else { $valid = (bool) $user['billing_vat_vies_valid']; } return $valid; } /** * @param $countryCode * @param $vatNumber * @return bool */ private function checkIfBillingVatByViesIsValidRequest($countryCode, $vatNumber): bool { try { $client = new SoapClient('http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl', [ 'exceptions' => true, 'connection_timeout' => 10, ]); $response = $client->checkVat(array( 'countryCode' => $countryCode, 'vatNumber' => $vatNumber )); return $response->valid; } catch (Exception $e) { return false; } } /** * Load Dependencies * * Load all dependencies for item * * @param array &$item Related item * @param array $dependencies Array of dependencies list to load or 'all' for full loading * * @return void */ public function loadDependencies(&$item, $dependencies = false) { if(!in_array('password', $dependencies)) { unset($item['password']); } $item['initials'] = getInitials($item['firstname'], $item['lastname']); $item['moment_read'] = [ 'full' => ucwords( Carbon::parse($item['moment'], CONFIG['defaults']['timezone'])->translatedFormat('j F Y') ), 'short' => ucwords( Carbon::parse($item['moment'], CONFIG['defaults']['timezone'])->translatedFormat('j M Y') ), ]; # Addresses if($dependencies AND !in_array('display', $dependencies) AND ($dependencies == 'all' OR in_array('addresses', $dependencies))) { $item['addresses'] = (new UserAddress)->getAllOrganizedByUserId($item['id']); } # Billing $item['billing'] = [ 'company' => $item['billing_company'], 'vat' => $item['billing_vat'], 'fiscal_code' => $item['billing_fiscal_code'], 'pec' => $item['billing_pec'], 'sdi' => $item['billing_sdi'], ]; unset($item['billing_company'], $item['billing_vat'], $item['billing_fiscal_code'], $item['billing_pec'], $item['billing_sdi']); } }