08 2024
This commit is contained in:
parent
04d677d37a
commit
bfa3bb1df4
1191 changed files with 637397 additions and 10619 deletions
48
app/Services/AboHelper.php
Normal file
48
app/Services/AboHelper.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use Yard;
|
||||
use App\User;
|
||||
use App\Models\UserAbo;
|
||||
use App\Models\UserAboOrder;
|
||||
use App\Models\ShoppingPayment;
|
||||
|
||||
|
||||
class AboHelper
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static function createNewAbo(ShoppingPayment $shopping_payment){
|
||||
|
||||
$payment_transaction = $shopping_payment->payment_transactions->last();
|
||||
$user_abo = UserAbo::create([
|
||||
'user_id' => $shopping_payment->shopping_order->auth_user_id,
|
||||
'shopping_user_id' => $shopping_payment->shopping_order->shopping_user_id,
|
||||
'is_for' => $shopping_payment->shopping_order->shopping_user->is_for,
|
||||
'payone_userid' => $payment_transaction->userid,
|
||||
'clearingtype' => $shopping_payment->clearingtype,
|
||||
'wallettype' => $shopping_payment->wallettype,
|
||||
'amount' => $shopping_payment->amount,
|
||||
'currency' => $shopping_payment->currency,
|
||||
'status' => 1,
|
||||
'abo_interval' => $shopping_payment->abo_interval,
|
||||
'start_date' => now(),
|
||||
'last_date' => now(),
|
||||
'next_date' => now()->addWeeks($shopping_payment->abo_interval),
|
||||
'next_abo_date' => $shopping_payment->created_at->addMonths($shopping_payment->abo_interval),
|
||||
'count' => 1,
|
||||
]);
|
||||
if($user_abo){
|
||||
UserAboOrder::create([
|
||||
'user_abo_id' => $user_abo->id,
|
||||
'shopping_order_id' => $shopping_payment->shopping_order_id,
|
||||
'status' => 1,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,172 +0,0 @@
|
|||
<?php
|
||||
namespace App\Services\BusinessPlan;
|
||||
|
||||
use App\User;
|
||||
use stdClass;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\UserLevel;
|
||||
use App\Models\UserBusiness;
|
||||
|
||||
|
||||
class TreeUserItem
|
||||
{
|
||||
public $items = [];
|
||||
private $date;
|
||||
public $lines = [];
|
||||
|
||||
public $user_level_active;
|
||||
|
||||
|
||||
|
||||
public function __construct($date)
|
||||
{
|
||||
$this->date = $date;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function makeUser(User $user){
|
||||
|
||||
$this->user_level_active = $user->user_level ? $user->user_level : null;
|
||||
$this->b_user = new UserBusiness();
|
||||
$fill = [
|
||||
'user_id' => $user->id,
|
||||
'month' => $this->date->month,
|
||||
'year' => $this->date->year,
|
||||
'm_level' => $user->m_level,
|
||||
'm_sponsor' => $user->m_sponsor,
|
||||
'user_level_name' => $user->user_level ? $user->user_level->name : '',
|
||||
'active_account' => $user->payment_account ? Carbon::parse($user->payment_account)->gt(Carbon::parse($this->date->start_date)) : false,
|
||||
'payment_account_date' => $user->payment_account ? $user->getPaymentAccountDateFormat(false) : NULL,
|
||||
'active_date' => $user->active_date ? $user->active_date : NULL,
|
||||
'm_account' => $user->account->m_account,
|
||||
'email' => $user->email,
|
||||
'first_name' => $user->account->first_name,
|
||||
'last_name' => $user->account->last_name,
|
||||
'sales_volume_points' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_points'),
|
||||
'sales_volume_points_shop' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_points_shop'),
|
||||
'sales_volume_points_sum' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_points_sum'),
|
||||
'sales_volume_total' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_total'),
|
||||
'sales_volume_total_shop' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_total_shop'),
|
||||
'sales_volume_total_sum' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_total_sum'),
|
||||
'margin' => $user->user_level_active ? $user->user_level_active->margin : 0,
|
||||
'margin_shop' => $user->user_level_active ? $user->user_level_active->margin_shop : 0,
|
||||
'qual_kp' => $user->user_level_active ? $user->user_level_active->qual_kp : 0,
|
||||
'qual_tp' => $user->user_level_active ? $user->user_level_active->qual_tp : 0,
|
||||
];
|
||||
$this->b_user->fill($fill);
|
||||
}
|
||||
|
||||
public function addUserID(){
|
||||
TreeCalcBot::addUserID($this->user_id);
|
||||
}
|
||||
|
||||
public function isQualKP(){
|
||||
return ($this->sales_volume_points_sum >= $this->qual_kp) ? true : false;
|
||||
}
|
||||
|
||||
public function getRestQualKP(){
|
||||
return $this->sales_volume_points_sum - $this->qual_kp;
|
||||
}
|
||||
|
||||
public function checkSponsor(){
|
||||
if($this->m_sponsor === null){
|
||||
$this->m_sponsor_name = 'Keinen Sponsor zugewiesen';
|
||||
return;
|
||||
}
|
||||
$user = User::find($this->m_sponsor);
|
||||
if($user){
|
||||
if($user->account){
|
||||
$this->m_sponsor_name = substr('Sponsor: '.$user->account->first_name.' '.$user->account->last_name.' | '.$user->email.' | '.$user->account->m_account, 0, 190);
|
||||
}else{
|
||||
$this->m_sponsor_name = 'Sponsor: '.$user->email;
|
||||
}
|
||||
return;
|
||||
}
|
||||
$this->m_sponsor_name = 'Sponsor wurde gelöscht.';
|
||||
return;
|
||||
}
|
||||
/*
|
||||
|
||||
'total_tp' => ,
|
||||
'total_qual_tp' => ,
|
||||
'commission_total' => ,
|
||||
'lines',
|
||||
'items',
|
||||
'qual_user_level_id'
|
||||
*/
|
||||
public function readParentsUser(){
|
||||
|
||||
$users = User::with('account')->select('users.*')
|
||||
->where('users.deleted_at', '=', null)
|
||||
->where('users.id', '!=', 1)
|
||||
->where('users.admin', "<", 4)
|
||||
->where('users.m_level', "!=", null)
|
||||
->where('users.m_sponsor', "=", $this->user_id) //<- need the id for parents / sponsors
|
||||
->where('users.payment_account', "!=", null)
|
||||
->where('users.active_date', "<=", $this->date->end_date)
|
||||
->get();
|
||||
dd($users);
|
||||
if($users){
|
||||
foreach($users as $user){
|
||||
$TreeUserItem = new TreeUserItem($this->date);
|
||||
$TreeUserItem->makeUser($user);
|
||||
$TreeUserItem->addUserID();
|
||||
$this->items[] = $TreeUserItem;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($this->items as $item){
|
||||
$item->readParentsUser();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function calcUserTP($line){
|
||||
if(!isset($this->lines[$line])){
|
||||
$this->lines[$line] = new stdClass();
|
||||
$this->lines[$line]->points = 0;
|
||||
}
|
||||
foreach($this->items as $item){
|
||||
if(count($item->items) > 0){
|
||||
$this->calcUserTP($line+1);
|
||||
}
|
||||
$this->lines[$line]->points += $item->sales_volume_points_sum;
|
||||
$this->total_tp += $item->sales_volume_points_sum;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function calcQualTP(){
|
||||
if($this->isQualKP()){
|
||||
$this->total_qual_tp = $this->total_tp + $this->getRestQualKP();
|
||||
$this->qual_user_level = UserLevel::where('qual_tp', '<=', $this->total_qual_tp)->where('pos', '<=', $this->user->user_level->pos)->orderBy('qual_tp', 'desc')->first();
|
||||
$this->commission_total = 0;
|
||||
if($this->qual_user_level){
|
||||
foreach($this->lines as $line => $values){
|
||||
$values->margin = $this->qual_user_level->{'pr_line_'.$line};
|
||||
if($line > 6){
|
||||
//wachstumsbonus
|
||||
$values->margin = $this->qual_user_level->growth_bonus;
|
||||
}
|
||||
$values->commission = round($values->points / 100 * $values->margin, 2);
|
||||
|
||||
$this->commission_total += $values->commission;
|
||||
$this->lines[$line] = $values;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function __get($property) {
|
||||
if (property_exists($this->b_user, $property)) {
|
||||
return $this->b_user->$property;
|
||||
}
|
||||
if (isset($this->b_user->{$property})) {
|
||||
return $this->b_user->{$property};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ use stdClass;
|
|||
use Carbon\Carbon;
|
||||
use App\Models\UserLevel;
|
||||
use App\Models\UserBusiness;
|
||||
use App\Services\TranslationHelper;
|
||||
use App\Models\UserBusinessStructure;
|
||||
|
||||
|
||||
|
|
@ -27,7 +28,7 @@ class BusinessUserItem
|
|||
|
||||
public function makeUser($user_id){
|
||||
|
||||
//check for user an load
|
||||
//check for user an load is saved
|
||||
$this->b_user = UserBusiness::where('user_id', $user_id)->where('month', $this->date->month)->where('year', $this->date->year)->first();
|
||||
if($this->b_user !== null){
|
||||
return;
|
||||
|
|
@ -53,6 +54,8 @@ class BusinessUserItem
|
|||
'email' => $user->email,
|
||||
'first_name' => $user->account->first_name,
|
||||
'last_name' => $user->account->last_name,
|
||||
'user_birthday' => $user->account->birthday,
|
||||
'user_phone' => $user->account->getPhoneNumber(),
|
||||
|
||||
'sales_volume_KP_points' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_KP_points'),
|
||||
'sales_volume_TP_points' => $user->getUserSalesVolumeBy($this->date->month, $this->date->year, 'sales_volume_TP_points'),
|
||||
|
|
@ -83,6 +86,11 @@ class BusinessUserItem
|
|||
|
||||
}
|
||||
|
||||
|
||||
public function getSalesVolumeTotalMargin(){
|
||||
return $this->b_user->getSalesVolumeTotalMargin();
|
||||
}
|
||||
|
||||
public function addUserID(){
|
||||
TreeCalcBot::addUserID($this->b_user->user_id);
|
||||
}
|
||||
|
|
@ -239,14 +247,17 @@ class BusinessUserItem
|
|||
$qualUserLevelNext = UserLevel::where('id', '=', $this->b_user->qual_user_level['next_id'])->orderBy('qual_pp', 'asc')->first();
|
||||
if($qualUserLevelNext){
|
||||
$this->b_user->qual_user_level_next = $qualUserLevelNext->toArray();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function setNextUserLevel(){
|
||||
dd($this->b_user->payline_points_qual_kp);
|
||||
$this->b_user->total_qual_pp = $this->total_pp + $this->getRestQualKP();
|
||||
$nextQualUserLevel = UserLevel::where('qual_pp', '<=', $this->total_qual_pp)->where('pos', '>', $this->user_level_active_pos)->orderBy('qual_pp', 'desc')->first();
|
||||
// $this->b_user->payline_points_qual_kp // das sind die Payline Points + Rest KP
|
||||
//$this->b_user->total_qual_pp = $this->total_pp + $this->getRestQualKP(); //hier werden alle Linien TP gezähle
|
||||
//$this->b_user->total_qual_pp = $this->total_pp + $this->getRestQualKP(); //hier werden alle Linien TP gezähle
|
||||
|
||||
$nextQualUserLevel = UserLevel::where('qual_pp', '<=', $this->payline_points_qual_kp)->where('pos', '>', $this->user_level_active_pos)->orderBy('qual_pp', 'desc')->first();
|
||||
if($nextQualUserLevel && $this->isQualKP()){
|
||||
$this->b_user->next_qual_user_level = $nextQualUserLevel->toArray();
|
||||
}else{
|
||||
|
|
@ -289,7 +300,7 @@ class BusinessUserItem
|
|||
->where('users.m_level', "!=", null)
|
||||
->where('users.m_sponsor', "=", $this->b_user->user_id) //<- need the id for parents / sponsors
|
||||
->where('users.payment_account', "!=", null)
|
||||
->where('users.active_date', "<=", $this->date->end_date)
|
||||
->where('users.active_date', "<=", $this->date->end_date) // wurde in dem Monat freigeschaltet
|
||||
->get();
|
||||
|
||||
if($users){
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ class ExportBot
|
|||
|
||||
$obj->user_id = $user->id;
|
||||
$obj->m_level = $user->m_level;
|
||||
$obj->level_name = $user->user_level ? $user->user_level->name : '';
|
||||
$obj->level_name = $user->user_level ? $user->user_level->getLang('name') : '';
|
||||
$obj->m_sponsor = $user->m_sponsor;
|
||||
$obj->sponsor_name = $sponsor_name;
|
||||
$obj->m_account = $user->m_account;
|
||||
|
|
@ -92,7 +92,7 @@ class ExportBot
|
|||
$obj->address_2 = $user->account->address_2;
|
||||
$obj->zipcode = $user->account->zipcode;
|
||||
$obj->city = $user->account->city;
|
||||
$obj->country_id = $user->account->country_id ? $user->account->country->de : "";
|
||||
$obj->country_id = $user->account->country_id ? $user->account->country->getLocated() : "";
|
||||
$pre_phone = $user->account->pre_phone_id != "" ? $user->account->pre_phone->phone." " : "";
|
||||
$pre_mobil = $user->account->pre_mobil_id != "" ? $user->account->pre_mobil->phone." " : "";
|
||||
$obj->phone = $pre_phone.$user->account->phone;
|
||||
|
|
|
|||
|
|
@ -84,9 +84,16 @@ class SalesPointsVolume
|
|||
break;
|
||||
case 4: //Gutschrift
|
||||
$month_points = self::add_KP_TP_Points($userSalesVolume, $month_points);
|
||||
$month_total_net += $userSalesVolume->total_net;
|
||||
|
||||
if($userSalesVolume->status_turnover === 2){
|
||||
$month_shop_total_net += $userSalesVolume->total_net;
|
||||
//ggf hier zu den Shop Points zählen wäre aber immer KP + TP kann nicht keine trennung bei month_shop_points
|
||||
}else{
|
||||
$month_total_net += $userSalesVolume->total_net;
|
||||
}
|
||||
|
||||
break;
|
||||
case 4: //Registrierung
|
||||
case 5: //Registrierung
|
||||
$month_points = self::add_KP_TP_Points($userSalesVolume, $month_points);
|
||||
$month_total_net += $userSalesVolume->total_net;
|
||||
break;
|
||||
|
|
@ -138,6 +145,8 @@ class SalesPointsVolume
|
|||
self::reCalculateSalesPointsVolume($user_sales_volume->user_id, $user_sales_volume->month, $user_sales_volume->year);
|
||||
}
|
||||
|
||||
return $user_sales_volume;
|
||||
|
||||
}
|
||||
|
||||
public static function setToUserAndReCalculate(UserSalesVolume $user_sales_volume, $user_id){
|
||||
|
|
@ -186,9 +195,10 @@ class SalesPointsVolume
|
|||
$user_sales_volume->message = 'geändert: '.date('d.m.Y');
|
||||
$user_sales_volume->info = $data['info'];
|
||||
$user_sales_volume->status_points = $data['status_points'];
|
||||
$user_sales_volume->status_turnover = isset($data['status_turnover']) ? intval($data['status_turnover']) : null;
|
||||
|
||||
$syslog = $user_sales_volume->syslog;
|
||||
$syslog[date('d.m.Y-h:i:s')] = 'edit points: #'.$old_points.' '.$user_sales_volume->points .' total: #'.$old_total_net.' '.$user_sales_volume->total_ne;
|
||||
$syslog[date('d.m.Y-h:i:s')] = 'edit points: #'.$old_points.' '.$user_sales_volume->points .' total: #'.$old_total_net.' '.$user_sales_volume->total_net;
|
||||
$user_sales_volume->syslog = $syslog;
|
||||
|
||||
$user_sales_volume->save();
|
||||
|
|
@ -216,6 +226,7 @@ class SalesPointsVolume
|
|||
$points = isset($data['points']) ? intval($data['points']) : 0;
|
||||
$syslog[date('d.m.Y-h:i:s')] = 'add points: #'.$points.' total: #'.$total_net;
|
||||
$status = isset($data['status']) ? intval($data['status']) : 4;
|
||||
$status_turnover = isset($data['status_turnover']) ? intval($data['status_turnover']) : null;
|
||||
|
||||
$user_sales_volume = UserSalesVolume::create([
|
||||
'user_id' => $user->id,
|
||||
|
|
@ -225,6 +236,7 @@ class SalesPointsVolume
|
|||
'date' => $date,
|
||||
'points' => $points,
|
||||
'status_points' => $data['status_points'],
|
||||
'status_turnover' => $status_turnover,
|
||||
'total_net' => $total_net,
|
||||
'message' => 'hinzugefügt: '.date('d.m.Y'),
|
||||
'info' => $data['info'],
|
||||
|
|
|
|||
|
|
@ -7,6 +7,130 @@ use App\Models\UserSalesVolume;
|
|||
|
||||
class SalesPointsVolumeHelper
|
||||
{
|
||||
|
||||
|
||||
//protected static $business_users_table = [];
|
||||
/*
|
||||
$sort = 'structur' || 'line'
|
||||
structur: nach baumstruktur sortiert, wird übergeben
|
||||
line: nach reihenfolge sortiert,
|
||||
*/
|
||||
private static $business_users_line = [];
|
||||
|
||||
private static $cbot = null;
|
||||
|
||||
|
||||
public static function getBusinessUsersTable($cbot, $sort = 'structur'){
|
||||
|
||||
self::$cbot = $cbot;
|
||||
if($sort == 'structur'){
|
||||
return self::getBusinessUsersTableStructur();
|
||||
}
|
||||
if($sort == 'line'){
|
||||
return self::getBusinessUsersTableLine();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/* getBusinessUsersTableStructur */
|
||||
private static function getBusinessUsersTableStructur(){
|
||||
$deep = 0;
|
||||
$ret = "";
|
||||
foreach(self::$cbot->business_users as $business_user){
|
||||
|
||||
$ret .= self::addTableItemStructur($business_user, $deep);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private static function addTableItemStructur($item, $deep) {
|
||||
$ret = self::setTableHTMLItemStructur($item, $deep);
|
||||
if($item->businessUserItems){
|
||||
foreach($item->businessUserItems as $parent){
|
||||
$ret .= self::addTableItemStructur($parent, $deep+1);
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private static function setTableHTMLItemStructur($item, $deep){
|
||||
|
||||
$pp = '';
|
||||
$margin = 0;
|
||||
$points = $item->sales_volume_points_KP_sum;
|
||||
$commission = 0;
|
||||
if($deep > 0){
|
||||
$pp = str_repeat(' ', $deep-1).'<div class=" line-height-1 my-2 badge badge-outline-success text-dark font-weight-bolder">'.$deep.'. '.__('team.PP').'</div>';
|
||||
$margin = self::$cbot->getKeybyLine($deep, 'margin');
|
||||
$commission = $points / 100 * $margin;
|
||||
}
|
||||
|
||||
$ret = '<tr>
|
||||
<td><div class="no-line-break">'.$pp.'</div></td>
|
||||
<td><span class="mr-1 ion ion-ios-contact '.($item->active_account ? 'text-primary' : 'text-danger').'"></span>'.$item->first_name.' '.$item->last_name.'
|
||||
</td>
|
||||
<td><div class="no-line-break">'.formatNumber($points, 0).' €</span></td>
|
||||
<td>'.formatNumber($margin, 1).' %</td>
|
||||
<td><div class="no-line-break">'.formatNumber($commission, 2).' €</span></td>
|
||||
<td><span class="small">'.$item->user_level_name.'</span></td>
|
||||
</tr>';
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private static function getBusinessUsersTableLine(){
|
||||
$deep = 0;
|
||||
$ret = "";
|
||||
foreach(self::$cbot->business_users as $business_user){
|
||||
self::addTableItemLine($business_user, $deep);
|
||||
}
|
||||
foreach(self::$business_users_line as $deep => $items){
|
||||
foreach($items as $item){
|
||||
$ret .= self::setTableHTMLItemLine($item, $deep);
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private static function addTableItemLine($item, $deep) {
|
||||
$item->deep = $deep;
|
||||
self::$business_users_line[$deep][] = $item;
|
||||
if($item->businessUserItems){
|
||||
foreach($item->businessUserItems as $parent){
|
||||
self::addTableItemLine($parent, $deep+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function setTableHTMLItemLine($item, $deep){
|
||||
|
||||
$pp = '';
|
||||
$margin = 0;
|
||||
$points = $item->sales_volume_points_KP_sum;
|
||||
$commission = 0;
|
||||
if($deep > 0){
|
||||
$pp = '<div class=" line-height-1 my-2 badge badge-outline-success text-dark font-weight-bolder">'.$deep.'. '.__('team.PP').'</div>';
|
||||
$margin = self::$cbot->getKeybyLine($deep, 'margin');
|
||||
$commission = $points / 100 * $margin;
|
||||
}
|
||||
//
|
||||
/*
|
||||
<th>{{__('tables.line')}}</th>
|
||||
<th>{{ __('shop.name') }}</th>
|
||||
<th>{{__('tables.points')}}</th>
|
||||
<th>{{__('tables.commission')}} %</th>
|
||||
<th>{{__('tables.commission')}} €</th>
|
||||
<th>{{ __('tables.level') }}</th>
|
||||
*/
|
||||
$ret = '<tr>
|
||||
<td><div class="no-line-break">'.$pp.'</div></td>
|
||||
<td><span class="mr-1 ion ion-ios-contact '.($item->active_account ? 'text-primary' : 'text-danger').'"></span>'.$item->first_name.' '.$item->last_name.'
|
||||
</td>
|
||||
<td><div class="no-line-break">'.formatNumber($points, 0).' €</span></td>
|
||||
<td>'.formatNumber($margin, 1).' %</td>
|
||||
<td><div class="no-line-break">'.formatNumber($commission, 2).' €</span></td>
|
||||
<td><span class="small">'.$item->user_level_name.'</span></td>
|
||||
</tr>';
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ class TreeCalcBot
|
|||
$this->date->start_date = $date->format('Y-m-d H:i:s');
|
||||
$this->date->end_date = $date->endOfMonth()->format('Y-m-d H:i:s');
|
||||
$this->init_from = $init_from;
|
||||
|
||||
}
|
||||
|
||||
public function initStructureAdmin($check = true)
|
||||
|
|
@ -63,14 +64,12 @@ class TreeCalcBot
|
|||
if(isset($this->business_users[0]) && $this->business_users[0]->sponsor){
|
||||
$this->readStoredSponsorUser($this->business_users[0]->sponsor->user_id);
|
||||
}
|
||||
|
||||
}else{
|
||||
$this->readParentsUsers();
|
||||
$this->readSponsorUser($user_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function initBusinesslUserDetail($user)
|
||||
{
|
||||
$this->business_user = new BusinessUserItem($this->date);
|
||||
|
|
@ -253,6 +252,7 @@ class TreeCalcBot
|
|||
$ret = '<ol class="dd-list">';
|
||||
foreach($this->business_users as $business_user){
|
||||
$ret .= $this->addItem($business_user, $deep);
|
||||
|
||||
}
|
||||
$ret .= '</ol>';
|
||||
return $ret;
|
||||
|
|
@ -269,7 +269,7 @@ class TreeCalcBot
|
|||
data-back=""
|
||||
data-modal="modal-xl"
|
||||
data-init_from="'.$this->init_from .'"
|
||||
data-route="'.route('modal_load').'"><span class="far fa-calculator"></span></button>';
|
||||
data-route="'.route('modal_load').'"><span class="fa fa-calculator"></span></button>';
|
||||
}
|
||||
return '<li class="dd-item dd-nodrag" data-id="'.$item->user_id.'">'.
|
||||
'<div class="dd-handle">
|
||||
|
|
@ -279,15 +279,20 @@ class TreeCalcBot
|
|||
</div>
|
||||
<div class="media-body ml-2">
|
||||
<span class="'.($item->active_account ? '' : 'text-muted').'">
|
||||
<span class="mr-1 ion ion-ios-contact '.($item->active_account ? 'text-primary' : 'text-danger').'"></span>
|
||||
<strong>'.$item->first_name.' '.$item->last_name.'</strong> <a href="mailto: '.$item->email.'">'.$item->email.'</a> <span class="badge badge-outline-default '.($item->active_account ? '' : 'text-muted').'">'.$item->user_level_name.' | '.$item->m_account.'</span>
|
||||
<a href="#" class="text-black" data-toggle="modal" data-target="#modals-load-content" data-id="'.$item->user_id.'" data-action="business-user-show" data-back="" data-modal="modal-md" data-init_from="'.$this->init_from .'" data-route="'.route('modal_load').'">
|
||||
<span class="mr-1 ion ion-ios-contact '.($item->active_account ? 'text-primary' : 'text-danger').'"></span> <strong>'.$item->first_name.' '.$item->last_name.'</strong>
|
||||
</a>
|
||||
<a href="mailto: '.$item->email.'">'.$item->email.'</a>
|
||||
'.($item->user_birthday ? ' | <i class="ion ion-ios-gift text-primary"></i> '.$item->user_birthday : '').'
|
||||
'.($item->user_phone ? ' | <i class="ion ion-ios-call text-primary"></i> '.$item->user_phone : '').'
|
||||
<span class="badge badge-outline-default '.($item->active_account ? '' : 'text-muted').'">'.\App\Services\TranslationHelper::transUserLevelName($item->user_level_name).' | '.$item->m_account.'</span>
|
||||
<br><span class="small">'.
|
||||
($item->active_account ?
|
||||
'<strong>Gesamte Points: '.$item->sales_volume_points_sum.'</strong> | E: '.$item->sales_volume_KP_points.' | S: '.$item->sales_volume_points_shop.' <strong>
|
||||
| Umsatz netto: '.formatNumber($item->sales_volume_total_sum).' €</strong> | E: '.formatNumber($item->sales_volume_total).' € | S: '.formatNumber($item->sales_volume_total_shop).' €'.
|
||||
'<strong>'.__('team.total_points').': '.$item->sales_volume_points_KP_sum.'</strong> | '.__('team.e').': '.$item->sales_volume_KP_points.' | '.__('team.s').': '.$item->sales_volume_points_shop.' <strong>
|
||||
| '.__('team.net_turnover').': '.formatNumber($item->sales_volume_total_sum).' €</strong> | '.__('team.e').': '.formatNumber($item->sales_volume_total).' € | '.__('team.s').': '.formatNumber($item->sales_volume_total_shop).' €'.
|
||||
$button
|
||||
:
|
||||
'Account bis: '.$item->payment_account_date).
|
||||
__('team.account_to').': '.$item->payment_account_date).
|
||||
'</span>
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -323,20 +328,25 @@ class TreeCalcBot
|
|||
$ret .= '<li class="dd-item dd-nodrag" data-id="'.$item->user_id.'">'.
|
||||
'<div class="dd-handle">
|
||||
<span class="'.($item->active_account ? '' : 'text-muted').'">
|
||||
<span class="mr-1 ion ion-ios-contact '.($item->active_account ? 'text-primary' : 'text-danger').'"></span>
|
||||
<strong>'.$item->first_name.' '.$item->last_name.'</strong> <a href="mailto: '.$item->email.'">'.$item->email.'</a> <span class="badge badge-outline-default '.($item->active_account ? '' : 'text-muted').'">'.$item->user_level_name.' | '.$item->m_account.'</span>
|
||||
<a href="#" class="text-black" data-toggle="modal" data-target="#modals-load-content" data-id="'.$item->user_id.'" data-action="business-user-show" data-back="" data-modal="modal-md" data-init_from="'.$this->init_from .'" data-route="'.route('modal_load').'">
|
||||
<span class="mr-1 ion ion-ios-contact '.($item->active_account ? 'text-primary' : 'text-danger').'"></span> <strong>'.$item->first_name.' '.$item->last_name.'</strong>
|
||||
</a>
|
||||
<a href="mailto: '.$item->email.'">'.$item->email.'</a>
|
||||
'.($item->user_birthday ? ' | <i class="ion ion-ios-gift text-primary"></i> '.$item->user_birthday : '').'
|
||||
'.($item->user_phone ? ' | <i class="ion ion-ios-call text-primary"></i> '.$item->user_phone : '').'
|
||||
<span class="badge badge-outline-default '.($item->active_account ? '' : 'text-muted').'">'.\App\Services\TranslationHelper::transUserLevelName($item->user_level_name).' | '.$item->m_account.'</span>
|
||||
<br><span class="small">'.
|
||||
($item->active_account ?
|
||||
'<strong>Gesamte Points: '.$item->sales_volume_points_sum.'</strong> | E: '.$item->sales_volume_KP_points.' | S: '.$item->sales_volume_points_shop.' <strong>
|
||||
| Umsatz netto: '.formatNumber($item->sales_volume_total_sum).' €</strong> | E: '.formatNumber($item->sales_volume_total).' € | S: '.formatNumber($item->sales_volume_total_shop).' €'.
|
||||
'<strong>'.__('team.total_points').': '.$item->sales_volume_points_KP_sum.'</strong> | '.__('team.e').': '.$item->sales_volume_KP_points.' | '.__('team.s').': '.$item->sales_volume_points_shop.' <strong>
|
||||
| '.__('team.net_turnover').': '.formatNumber($item->sales_volume_total_sum).' €</strong> | '.__('team.e').': '.formatNumber($item->sales_volume_total).' € | '.__('team.s').': '.formatNumber($item->sales_volume_total_shop).' €'.
|
||||
' | <button type="button" class="btn icon-btn btn-xs btn-secondary" data-toggle="modal" data-target="#modals-load-content"
|
||||
data-id="'.$item->user_id.'"
|
||||
data-action="business-user-detail"
|
||||
data-back=""
|
||||
data-modal="modal-xl"
|
||||
data-route="'.route('modal_load').'"><span class="far fa-calculator"></span></button>'
|
||||
data-route="'.route('modal_load').'"><span class="fa fa-calculator"></span></button>'
|
||||
:
|
||||
'Account bis: '.$item->payment_account_date).
|
||||
__('team.account_to').' '.$item->payment_account_date).
|
||||
'<br>'.$item->m_sponsor_name.
|
||||
'</span>
|
||||
</span>
|
||||
|
|
@ -349,20 +359,25 @@ class TreeCalcBot
|
|||
public function makeSponsorHtml(){
|
||||
|
||||
if($this->sponsor){
|
||||
//' | <a href="' . route('admin_business_user_detail', [$this->sponsor->id]) . '" class="btn icon-btn btn-xs btn-secondary"><span class="far fa-calculator"></span></a>'
|
||||
//' | <a href="' . route('admin_business_user_detail', [$this->sponsor->id]) . '" class="btn icon-btn btn-xs btn-secondary"><span class="fa fa-calculator"></span></a>'
|
||||
$ret = '<li class="dd-item dd-nodrag" data-id="">'.
|
||||
'<div class="dd-handle">
|
||||
<span class="'.($this->sponsor->active_account ? '' : 'text-muted').'">
|
||||
<span class="mr-1 ion ion-ios-contact '.($this->sponsor->active_account ? 'text-primary' : 'text-danger').'"></span>
|
||||
<strong>'.$this->sponsor->first_name.' '.$this->sponsor->last_name.'</strong> <a href="mailto: '.$this->sponsor->email.'">'.$this->sponsor->email.'</a> <span class="badge badge-outline-default '.($this->sponsor->active_account ? '' : 'text-muted').'">'.$this->sponsor->user_level_name.' | '.$this->sponsor->m_account.'</span>';
|
||||
<a href="#" class="text-black" data-toggle="modal" data-target="#modals-load-content" data-id="'.$this->sponsor->user_id.'" data-action="business-user-show" data-back="" data-init_from="'.$this->init_from .'" data-modal="modal-md" data-route="'.route('modal_load').'">
|
||||
<span class="mr-1 ion ion-ios-contact '.($this->sponsor->active_account ? 'text-primary' : 'text-danger').'"></span> <strong>'.$this->sponsor->first_name.' '.$this->sponsor->last_name.'</strong>
|
||||
</a>
|
||||
<a href="mailto: '.$this->sponsor->email.'">'.$this->sponsor->email.'</a>
|
||||
'.($this->sponsor->user_birthday ? ' | <i class="ion ion-ios-gift text-primary"></i> '.$this->sponsor->user_birthday : '').'
|
||||
'.($this->sponsor->user_phone ? ' | <i class="ion ion-ios-call text-primary"></i> '.$this->sponsor->user_phone : '').'
|
||||
<span class="badge badge-outline-default '.($this->sponsor->active_account ? '' : 'text-muted').'">'.\App\Services\TranslationHelper::transUserLevelName($this->sponsor->user_level_name).' | '.$this->sponsor->m_account.'</span>';
|
||||
|
||||
if($this->init_from === 'admin'){
|
||||
$ret .= '<br><span class="small">'.
|
||||
($this->sponsor->active_account ?
|
||||
'<strong>Gesamte Points: '.$this->sponsor->sales_volume_points_sum.'</strong> | E: '.$this->sponsor->sales_volume_KP_points.' | S: '.$this->sponsor->sales_volume_points_shop.' <strong>
|
||||
| Umsatz netto: '.formatNumber($this->sponsor->sales_volume_total_sum).' €</strong> | E: '.formatNumber($this->sponsor->sales_volume_total).' € | S: '.formatNumber($this->sponsor->sales_volume_total_shop).' €'
|
||||
'<strong>'.__('team.total_points').': '.$this->sponsor->sales_volume_points_KP_sum.'</strong> | '.__('team.e').': '.$this->sponsor->sales_volume_KP_points.' | '.__('team.s').': '.$this->sponsor->sales_volume_points_shop.' <strong>
|
||||
| '.__('team.net_turnover').': '.formatNumber($this->sponsor->sales_volume_total_sum).' €</strong> | '.__('team.e').': '.formatNumber($this->sponsor->sales_volume_total).' € | '.__('team.s').': '.formatNumber($this->sponsor->sales_volume_total_shop).' €'
|
||||
:
|
||||
'Account bis: '.$this->sponsor->payment_account_date).
|
||||
__('team.account_to').' '.$this->sponsor->payment_account_date).
|
||||
'</span>';
|
||||
}
|
||||
$ret .= '</span>
|
||||
|
|
@ -371,9 +386,7 @@ class TreeCalcBot
|
|||
|
||||
return $ret;
|
||||
}
|
||||
return 'Keinen Sponsor zugewiesen';
|
||||
|
||||
|
||||
return __('team.no_sponsor_assigned');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,379 +0,0 @@
|
|||
<?php
|
||||
namespace App\Services\BusinessPlan;
|
||||
|
||||
use App\User;
|
||||
use stdClass;
|
||||
use Carbon;
|
||||
use App\Models\UserBusinessStructure;
|
||||
|
||||
class ExportBot
|
||||
{
|
||||
public $date;
|
||||
public $business_user;
|
||||
|
||||
public $business_users = [];
|
||||
public $parentless = [];
|
||||
|
||||
private $sponsor;
|
||||
private $init_from;
|
||||
private static $userIDs = [];
|
||||
|
||||
public static function addUserID($id){
|
||||
self::$userIDs[$id] = $id;
|
||||
}
|
||||
|
||||
public function __construct($month, $year, $init_from = 'member')
|
||||
{
|
||||
$this->date = new stdClass();
|
||||
$date = Carbon::parse($year.'-'.$month.'-1');
|
||||
$this->date->month = $month;
|
||||
$this->date->year = $year;
|
||||
$this->date->start_date = $date->format('Y-m-d H:i:s');
|
||||
$this->date->end_date = $date->endOfMonth()->format('Y-m-d H:i:s');
|
||||
$this->init_from = $init_from;
|
||||
}
|
||||
|
||||
public function initStructureAdmin($check = true)
|
||||
{
|
||||
//check is month is saved.
|
||||
if($check && $UserBusinessStructure = self::isFromStored($this->date->month, $this->date->year)){
|
||||
$this->readStoredRootUsers($UserBusinessStructure);
|
||||
$this->readStoredParentsUsers($UserBusinessStructure);
|
||||
$this->readStoredParentlessUser($UserBusinessStructure);
|
||||
}else{
|
||||
$this->readRootUsers();
|
||||
$this->readParentsUsers();
|
||||
$this->readParentlessUser();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function initStructureUser($user_id)
|
||||
{
|
||||
|
||||
$BusinessUserItem = new BusinessUserItem($this->date);
|
||||
$BusinessUserItem->makeUser($user_id);
|
||||
$BusinessUserItem->addUserID();
|
||||
$this->business_users[] = $BusinessUserItem;
|
||||
|
||||
//check is month is saved.
|
||||
if($UserBusinessStructure = self::isFromStored($this->date->month, $this->date->year)){
|
||||
$this->readStoredParentsUsers($UserBusinessStructure);
|
||||
|
||||
if(isset($this->business_users[0]) && $this->business_users[0]->sponsor){
|
||||
$this->readStoredSponsorUser($this->business_users[0]->sponsor->user_id);
|
||||
}
|
||||
|
||||
}else{
|
||||
$this->readParentsUsers();
|
||||
$this->readSponsorUser($user_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function initBusinesslUserDetail($user)
|
||||
{
|
||||
$this->business_user = new BusinessUserItem($this->date);
|
||||
$this->business_user->makeUser($user->id);
|
||||
$this->business_user->checkSponsor($user);
|
||||
if(!$this->business_user->isSave()){
|
||||
//Aufbau der Struktur für den User in die unendliche Tiefe.
|
||||
$this->business_user->readParentsBusinessUsers();
|
||||
//calculate Points in Lines
|
||||
if(count($this->business_user->businessUserItems) > 0){
|
||||
$this->calcUserPoints($this->business_user->businessUserItems, 1);
|
||||
}
|
||||
//qualifikation nach qual_kp (KundenPoints) und qual_pp (PaylinePoints)
|
||||
$this->business_user->calcQualPP();
|
||||
}
|
||||
}
|
||||
|
||||
/*public function storeBusinesslUser()
|
||||
{
|
||||
$this->business_user->storeUser();
|
||||
}*/
|
||||
|
||||
public static function isFromStored($month, $year){
|
||||
//when is stored an completed
|
||||
$UserBusinessStructure = UserBusinessStructure::where('year', $year)->where('month', $month)->first();
|
||||
if($UserBusinessStructure && $UserBusinessStructure->completed){
|
||||
return $UserBusinessStructure;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function calcUserPoints($businessUserItems, $line){
|
||||
if(!isset($this->business_user->business_lines[$line])){
|
||||
$obj = new stdClass();
|
||||
$obj->points = 0;
|
||||
$this->business_user->addBusinessLineToUser($line, $obj);
|
||||
}
|
||||
foreach($businessUserItems as $business_user_item){
|
||||
if(count($business_user_item->businessUserItems) > 0){
|
||||
$this->calcUserPoints($business_user_item->businessUserItems, $line+1);
|
||||
}
|
||||
//business_lines points nach line
|
||||
$this->business_user->addBusinessLinePoints($line, $business_user_item->sales_volume_points_TP_sum); //TP + Shop Points
|
||||
//total_pp gesamte Punkte
|
||||
$this->business_user->addTotalTP($business_user_item->sales_volume_points_TP_sum); //TP + Shop Points
|
||||
}
|
||||
}
|
||||
|
||||
public function getGrowthBonus(){
|
||||
if(count($this->business_user->business_lines) > 6){
|
||||
$b_lines = $this->business_user->business_lines->toArray();
|
||||
return array_slice($b_lines, 6);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
public function getKeybyLine($line, $key){
|
||||
if($this->business_user->business_lines){
|
||||
$b_lines = $this->business_user->business_lines;
|
||||
if(isset($b_lines[$line])){
|
||||
if($b_lines[$line] instanceof stdClass){
|
||||
if(isset($b_lines[$line]->{$key})){
|
||||
return $b_lines[$line]->{$key};
|
||||
}
|
||||
}else{
|
||||
if(isset($b_lines[$line][$key])){
|
||||
return $b_lines[$line][$key];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//* reading from current*//
|
||||
private function readRootUsers(){
|
||||
$users = User::with('account')->select('users.*')
|
||||
->where('users.deleted_at', '=', null)
|
||||
->where('users.id', '!=', 1)
|
||||
->where('users.admin', "<", 4)
|
||||
->where('users.m_level', "!=", null)
|
||||
->where('users.m_sponsor', "=", null)
|
||||
->where('users.payment_account', "!=", null)
|
||||
->where('users.active_date', "<=", $this->date->end_date)
|
||||
->get();
|
||||
if($users){
|
||||
foreach($users as $user){
|
||||
$BusinessUserItem = new BusinessUserItem($this->date);
|
||||
$BusinessUserItem->makeUser($user->id);
|
||||
$BusinessUserItem->addUserID();
|
||||
$this->business_users[] = $BusinessUserItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function readParentsUsers(){
|
||||
foreach($this->business_users as $business_user){
|
||||
$business_user->readParentsBusinessUsers();
|
||||
}
|
||||
}
|
||||
|
||||
private function readParentlessUser(){
|
||||
$users = User::with('account')->select('users.*')
|
||||
->where('users.deleted_at', '=', null)
|
||||
->where('users.id', '!=', 1)
|
||||
->where('users.admin', "<", 4)
|
||||
->where('users.payment_account', "!=", null)
|
||||
->where('users.active_date', "<=", $this->date->end_date)
|
||||
->get();
|
||||
|
||||
foreach($users as $user){
|
||||
if(!isset(self::$userIDs[$user->id])){
|
||||
$BusinessUserItem = new BusinessUserItem($this->date);
|
||||
$BusinessUserItem->makeUser($user->id);
|
||||
$this->parentless[] = $BusinessUserItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//* reading from stored*//
|
||||
private function readStoredRootUsers(UserBusinessStructure $userBusinessStructure){
|
||||
//first level is root
|
||||
if($userBusinessStructure->structure){
|
||||
foreach($userBusinessStructure->structure as $obj){
|
||||
$BusinessUserItem = new BusinessUserItem($this->date);
|
||||
$BusinessUserItem->makeUser($obj->user_id);
|
||||
$BusinessUserItem->addUserID();
|
||||
$this->business_users[] = $BusinessUserItem;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function readStoredParentsUsers(UserBusinessStructure $userBusinessStructure){
|
||||
foreach($this->business_users as $business_user){
|
||||
$business_user->readStoredParentsBusinessUsers($userBusinessStructure->structure);
|
||||
}
|
||||
}
|
||||
|
||||
private function readStoredParentlessUser(UserBusinessStructure $userBusinessStructure){
|
||||
if($userBusinessStructure->parentless){
|
||||
foreach($userBusinessStructure->parentless as $obj){
|
||||
if(!isset(self::$userIDs[$obj->user_id])){
|
||||
$BusinessUserItem = new BusinessUserItem($this->date);
|
||||
$BusinessUserItem->makeUser($obj->user_id);
|
||||
$this->parentless[] = $BusinessUserItem;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function readSponsorUser($user_id){
|
||||
$user = User::find($user_id);
|
||||
$userSponsor = User::find($user->m_sponsor);
|
||||
if($userSponsor){
|
||||
$this->sponsor = new BusinessUserItem($this->date);
|
||||
$this->sponsor->makeUser($userSponsor->id);
|
||||
}
|
||||
}
|
||||
|
||||
public function readStoredSponsorUser($user_id){
|
||||
|
||||
$this->sponsor = new BusinessUserItem($this->date);
|
||||
$this->sponsor->makeUser($user_id);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function getItems(){
|
||||
return $this->business_users;
|
||||
}
|
||||
|
||||
public function makeHtmlTree(){
|
||||
$deep = 0;
|
||||
$ret = '<ol class="dd-list">';
|
||||
foreach($this->business_users as $business_user){
|
||||
$ret .= $this->addItem($business_user, $deep);
|
||||
}
|
||||
$ret .= '</ol>';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
private function addItem($item, $deep){
|
||||
|
||||
$button = '';
|
||||
|
||||
if(($this->init_from === 'admin' && \Auth::user()->isAdmin()) || ($this->init_from === 'member')){ // && \Auth::user()->id === $item->user_id
|
||||
$button = ' | <button type="button" class="btn icon-btn btn-xs btn-secondary" data-toggle="modal" data-target="#modals-load-content"
|
||||
data-id="'.$item->user_id.'"
|
||||
data-action="business-user-detail"
|
||||
data-back=""
|
||||
data-modal="modal-xl"
|
||||
data-init_from="'.$this->init_from .'"
|
||||
data-route="'.route('modal_load').'"><span class="far fa-calculator"></span></button>';
|
||||
}
|
||||
return '<li class="dd-item dd-nodrag" data-id="'.$item->user_id.'">'.
|
||||
'<div class="dd-handle">
|
||||
<div class="media align-items-center">
|
||||
<div class="d-flex flex-column justify-content-center align-items-center">
|
||||
'.(($deep > 0) ? '<div class="text-large font-weight-bolder line-height-1 my-2 text-secondary badge badge-outline-secondary">'.$deep.'</div>' : '').'
|
||||
</div>
|
||||
<div class="media-body ml-2">
|
||||
<span class="'.($item->active_account ? '' : 'text-muted').'">
|
||||
<span class="mr-1 ion ion-ios-contact '.($item->active_account ? 'text-primary' : 'text-danger').'"></span>
|
||||
<strong>'.$item->first_name.' '.$item->last_name.'</strong> <a href="mailto: '.$item->email.'">'.$item->email.'</a> <span class="badge badge-outline-default '.($item->active_account ? '' : 'text-muted').'">'.$item->user_level_name.' | '.$item->m_account.'</span>
|
||||
<br><span class="small">'.
|
||||
($item->active_account ?
|
||||
'<strong>Gesamte Points: '.$item->sales_volume_points_sum.'</strong> | E: '.$item->sales_volume_KP_points.' | S: '.$item->sales_volume_points_shop.' <strong>
|
||||
| Umsatz netto: '.formatNumber($item->sales_volume_total_sum).' €</strong> | E: '.formatNumber($item->sales_volume_total).' € | S: '.formatNumber($item->sales_volume_total_shop).' €'.
|
||||
$button
|
||||
:
|
||||
'Account bis: '.$item->payment_account_date).
|
||||
'</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>'.
|
||||
$this->addParentItem($item, $deep).
|
||||
'</li>';
|
||||
|
||||
}
|
||||
|
||||
private function addParentItem($item, $deep){
|
||||
if($item->businessUserItems){
|
||||
$ret = '<ol class="dd-list dd-nodrag">';
|
||||
foreach($item->businessUserItems as $parent){
|
||||
$ret .= $this->addItem($parent, $deep+1);
|
||||
}
|
||||
$ret .='</ol>';
|
||||
return $ret;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
public function isParentless(){
|
||||
return $this->parentless ? true : false;
|
||||
}
|
||||
|
||||
public function makeParentlessHtml(){
|
||||
$ret = "";
|
||||
foreach($this->parentless as $item){
|
||||
$ret .= '<li class="dd-item dd-nodrag" data-id="'.$item->user_id.'">'.
|
||||
'<div class="dd-handle">
|
||||
<span class="'.($item->active_account ? '' : 'text-muted').'">
|
||||
<span class="mr-1 ion ion-ios-contact '.($item->active_account ? 'text-primary' : 'text-danger').'"></span>
|
||||
<strong>'.$item->first_name.' '.$item->last_name.'</strong> <a href="mailto: '.$item->email.'">'.$item->email.'</a> <span class="badge badge-outline-default '.($item->active_account ? '' : 'text-muted').'">'.$item->user_level_name.' | '.$item->m_account.'</span>
|
||||
<br><span class="small">'.
|
||||
($item->active_account ?
|
||||
'<strong>Gesamte Points: '.$item->sales_volume_points_sum.'</strong> | E: '.$item->sales_volume_KP_points.' | S: '.$item->sales_volume_points_shop.' <strong>
|
||||
| Umsatz netto: '.formatNumber($item->sales_volume_total_sum).' €</strong> | E: '.formatNumber($item->sales_volume_total).' € | S: '.formatNumber($item->sales_volume_total_shop).' €'.
|
||||
' | <button type="button" class="btn icon-btn btn-xs btn-secondary" data-toggle="modal" data-target="#modals-load-content"
|
||||
data-id="'.$item->user_id.'"
|
||||
data-action="business-user-detail"
|
||||
data-back=""
|
||||
data-modal="modal-xl"
|
||||
data-route="'.route('modal_load').'"><span class="far fa-calculator"></span></button>'
|
||||
:
|
||||
'Account bis: '.$item->payment_account_date).
|
||||
'<br>'.$item->m_sponsor_name.
|
||||
'</span>
|
||||
</span>
|
||||
</div>'.
|
||||
'</li>';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function makeSponsorHtml(){
|
||||
|
||||
if($this->sponsor){
|
||||
//' | <a href="' . route('admin_business_user_detail', [$this->sponsor->id]) . '" class="btn icon-btn btn-xs btn-secondary"><span class="far fa-calculator"></span></a>'
|
||||
$ret = '<li class="dd-item dd-nodrag" data-id="">'.
|
||||
'<div class="dd-handle">
|
||||
<span class="'.($this->sponsor->active_account ? '' : 'text-muted').'">
|
||||
<span class="mr-1 ion ion-ios-contact '.($this->sponsor->active_account ? 'text-primary' : 'text-danger').'"></span>
|
||||
<strong>'.$this->sponsor->first_name.' '.$this->sponsor->last_name.'</strong> <a href="mailto: '.$this->sponsor->email.'">'.$this->sponsor->email.'</a> <span class="badge badge-outline-default '.($this->sponsor->active_account ? '' : 'text-muted').'">'.$this->sponsor->user_level_name.' | '.$this->sponsor->m_account.'</span>';
|
||||
|
||||
if($this->init_from === 'admin'){
|
||||
$ret .= '<br><span class="small">'.
|
||||
($this->sponsor->active_account ?
|
||||
'<strong>Gesamte Points: '.$this->sponsor->sales_volume_points_sum.'</strong> | E: '.$this->sponsor->sales_volume_KP_points.' | S: '.$this->sponsor->sales_volume_points_shop.' <strong>
|
||||
| Umsatz netto: '.formatNumber($this->sponsor->sales_volume_total_sum).' €</strong> | E: '.formatNumber($this->sponsor->sales_volume_total).' € | S: '.formatNumber($this->sponsor->sales_volume_total_shop).' €'
|
||||
:
|
||||
'Account bis: '.$this->sponsor->payment_account_date).
|
||||
'</span>';
|
||||
}
|
||||
$ret .= '</span>
|
||||
</div>
|
||||
</li>';
|
||||
|
||||
return $ret;
|
||||
}
|
||||
return 'Keinen Sponsor zugewiesen';
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -35,10 +35,18 @@ class Credit
|
|||
return "/credit/".\Carbon::parse($credit_date)->format('Y/m/');
|
||||
}
|
||||
|
||||
public static function getCreditDetailStorageDir($credit_date){
|
||||
return "/credit_details/".\Carbon::parse($credit_date)->format('Y/m/');
|
||||
}
|
||||
|
||||
public static function makeCreditFilename($credit_number){
|
||||
return $credit_number."-MIVITA-Gutschrift.pdf";
|
||||
}
|
||||
|
||||
public static function makeCreditDetailFilename($credit_number){
|
||||
return $credit_number."-MIVITA-Report.pdf";
|
||||
}
|
||||
|
||||
public static function isCredit(UserCredit $user_credit){
|
||||
return $user_credit->isCredit();
|
||||
}
|
||||
|
|
@ -79,6 +87,6 @@ class Credit
|
|||
}else{
|
||||
$bcc[] = config('app.checkout_mail');
|
||||
}
|
||||
Mail::to($email)->bcc($bcc)->send(new MailCredit($user_credit));
|
||||
Mail::to($email)->bcc($bcc)->locale($user_credit->user->getLocale())->send(new MailCredit($user_credit));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class CustomerPriority
|
|||
if($entryExistsLike){
|
||||
if(self::entryExistsLike($shopping_user)){ //existiert die Email bei einem anderem member?
|
||||
if($mail){ //send mail
|
||||
Mail::to(config('app.info_mail'))->send(new MailInfo($shopping_user, 'check_is_like_customer'));
|
||||
Mail::to(config('app.priority_mail'))->send(new MailInfo($shopping_user, 'check_is_like_customer'));
|
||||
}
|
||||
return 'exists';
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ class CustomerPriority
|
|||
}
|
||||
if(self::entryLike($shopping_user)){ //existiert die Adresse bei einem anderem member?
|
||||
if($mail){ //send mail
|
||||
Mail::to(config('app.info_mail'))->send(new MailInfo($shopping_user, 'check_is_like_customer'));
|
||||
Mail::to(config('app.priority_mail'))->send(new MailInfo($shopping_user, 'check_is_like_customer'));
|
||||
}
|
||||
return 'like'.$shopping_user->member_id;
|
||||
}
|
||||
|
|
@ -178,7 +178,7 @@ class CustomerPriority
|
|||
}
|
||||
//look for entry
|
||||
if($matches && $mail){ //send mail
|
||||
Mail::to(config('app.info_mail'))->send(new MailInfo($shopping_user, 'change_is_like_customer', $change));
|
||||
Mail::to(config('app.priority_mail'))->send(new MailInfo($shopping_user, 'change_is_like_customer', $change));
|
||||
}
|
||||
|
||||
return $ret;
|
||||
|
|
@ -190,7 +190,7 @@ class CustomerPriority
|
|||
public static function checkNewOne($shopping_user, $mail=false){
|
||||
if(self::entryLike($shopping_user)){
|
||||
if($mail){ //send mail
|
||||
Mail::to(config('app.info_mail'))->send(new MailInfo($shopping_user, 'check_is_like_customer'));
|
||||
Mail::to(config('app.priority_mail'))->send(new MailInfo($shopping_user, 'check_is_like_customer'));
|
||||
}
|
||||
//return 'like';
|
||||
}
|
||||
|
|
|
|||
108
app/Services/DcHelper.php
Normal file
108
app/Services/DcHelper.php
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\Tag;
|
||||
use App\Models\DcTag;
|
||||
use App\Models\FileTag;
|
||||
use App\Models\DcFileTag;
|
||||
|
||||
class DcHelper {
|
||||
|
||||
|
||||
public static $points;
|
||||
|
||||
public static function getTransChange(){
|
||||
|
||||
$langs = [
|
||||
'de' => ['name' => 'German', 'script' => 'Latn', 'native' => 'Deutsch', 'regional' => 'de_DE'],
|
||||
'en' => ['name' => 'English', 'script' => 'Latn', 'native' => 'English', 'regional' => 'en_GB'],
|
||||
'es' => ['name' => 'Spanish', 'script' => 'Latn', 'native' => 'español', 'regional' => 'es_ES'],
|
||||
];
|
||||
|
||||
$ret = [];
|
||||
foreach($langs as $code => $lang){
|
||||
$ret[strtolower($code)] = strtolower($lang['native']);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function makeNestableList($category_id){
|
||||
$tags = DcTag::where('category_id', $category_id)->orderBy('pos')->get();
|
||||
$out = "";
|
||||
foreach ($tags as $tag){
|
||||
|
||||
$out .= '<li class="dd-item" data-id="'.$tag->id.'">
|
||||
<span class="pull-right">
|
||||
<a href="#" class="btn btn-sm mt-1 nestable_update_btn" data-action="update-tag-active" data-target="self" data-id="'.$tag->id.'" data-url="'.route('admin_downloadcenter_item_store', ['update_ajax']).'">
|
||||
' . ($tag->active ? '<i class="fa fa-eye text-success"></i>' : '<i class="fa fa-eye-slash text-danger"></i>') . '
|
||||
</a>
|
||||
<a href="'.route('admin_downloadcenter_item_delete', ['obj' => 'tag', 'id'=> $tag->id]).'" class="btn btn-sm mt-1 nestable_list_delete"><i class="fa fa-trash text-danger"></i></a>
|
||||
</span>
|
||||
<div class="dd-handle">
|
||||
'.$tag->name.'
|
||||
</div>
|
||||
</li>';
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
|
||||
public static function makeNestableListCheckbox($category_id, $file_id){
|
||||
|
||||
$tags = DcTag::where('category_id', $category_id)->orderBy('pos')->get();
|
||||
$file_tags = DcFileTag::where('file_id', $file_id)->get();
|
||||
|
||||
$search = array();
|
||||
foreach ($file_tags as $file_tag) {
|
||||
$search[] = $file_tag->tag_id;
|
||||
}
|
||||
|
||||
$out = "";
|
||||
foreach ($tags as $tag){
|
||||
$out .= '<li class="dd-item" data-id="'.$tag->id.'">
|
||||
<div class="dd-handle dd-nodrag">
|
||||
<label class="custom-control custom-checkbox m-0" for="nestable_check_'.$tag->id.'">
|
||||
<input type="checkbox" class="custom-control-input" name="nestable_check[]" id="nestable_check_'.$tag->id.'" value="'.$tag->id.'" '.(array_search($tag->id, $search) !== FALSE ? 'checked="checked"' : '').'>
|
||||
<span class="custom-control-label"> '.$tag->name.' </span>
|
||||
</label>
|
||||
</div>
|
||||
</li>';
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public static function makeFilterList($filter_list, $split = false, $chunk = false){
|
||||
|
||||
$out = "";
|
||||
$splitOn = 0;
|
||||
if($split){
|
||||
$count = count($filter_list);
|
||||
if($count > 0){
|
||||
$splitOn = intval(ceil($count / $split));
|
||||
$filter_chunk = array_chunk($filter_list, $splitOn, true);
|
||||
$filter_list = $filter_chunk[$chunk];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach($filter_list as $category_id => $value){
|
||||
$out .= '<label class="form-label" for="category_'.$category_id.'">'.$value['name'].'</label>';
|
||||
$out .= '<select class="selectpicker category-filter" name="categories['.$category_id.'][]" id="category_'.$category_id.'" data-style="btn-light" data-live-search="true" multiple>';
|
||||
foreach($value['items'] as $tag){
|
||||
$out .= '<option value="'.$tag->id.'">'.$tag->name.' ('.$tag->count.')</option>';
|
||||
|
||||
}
|
||||
$out .= '</select>';
|
||||
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
private function getAttributesOptions($ids = array(), $all = true){
|
||||
$ret = "";
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -16,31 +16,40 @@ class HTMLHelper
|
|||
|
||||
|
||||
public static $months = [
|
||||
1 => 'Januar',
|
||||
2 => 'Februar',
|
||||
3 => 'März',
|
||||
1 => 'January',
|
||||
2 => 'February',
|
||||
3 => 'March',
|
||||
4 => 'April',
|
||||
5 => 'Mai',
|
||||
6 => 'Juni',
|
||||
7 => 'Juli',
|
||||
5 => 'May',
|
||||
6 => 'June',
|
||||
7 => 'July',
|
||||
8 => 'August',
|
||||
9 => 'September',
|
||||
10 => 'Oktober',
|
||||
10 => 'October',
|
||||
11 => 'November',
|
||||
12 => 'Dezember'
|
||||
12 => 'December'
|
||||
];
|
||||
|
||||
|
||||
private static $roles = [
|
||||
0 => 'Kunde',
|
||||
1 => 'Admin',
|
||||
2 => 'SuperAdmin',
|
||||
3 => 'SySAdmin',
|
||||
1 => 'VIP',
|
||||
2 => 'Admin',
|
||||
3 => 'SuperAdmin',
|
||||
4 => 'SySAdmin',
|
||||
];
|
||||
|
||||
|
||||
public static function getMonth($i){
|
||||
return self::$months[intval($i)];
|
||||
return trans('cal.months.'.self::$months[intval($i)]);
|
||||
}
|
||||
|
||||
public static function getTransMonths(){
|
||||
$ret = [];
|
||||
foreach(self::$months as $key=>$val){
|
||||
$ret[$key] = trans('cal.months.'.$val);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getYearRange($start = 2021)
|
||||
|
|
@ -49,7 +58,6 @@ class HTMLHelper
|
|||
return array_reverse(range($start, $end));
|
||||
}
|
||||
|
||||
|
||||
public static function getRoleLabel($role_id = 0){
|
||||
return '<span class="badge badge-pill '.self::getLabel($role_id).'">'.self::$roles[$role_id].'</span>';
|
||||
}
|
||||
|
|
@ -60,14 +68,17 @@ class HTMLHelper
|
|||
return 'badge-default';
|
||||
break;
|
||||
case 1:
|
||||
return 'badge-warning';
|
||||
return 'badge-secondary';
|
||||
break;
|
||||
case 2:
|
||||
return 'badge-primary';
|
||||
return 'badge-warning';
|
||||
break;
|
||||
case 3:
|
||||
return 'badge-primary';
|
||||
break;
|
||||
case 4:
|
||||
return 'badge-primary';
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -93,11 +104,28 @@ class HTMLHelper
|
|||
return $ret;
|
||||
}
|
||||
|
||||
public static function getAboIntervallWeeks($default = 1){
|
||||
$values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
|
||||
$ret = "";
|
||||
foreach ($values as $value){
|
||||
$attr = ($value == $default) ? 'selected="selected"' : '';
|
||||
$str = self::getAboWeeksLang($value);
|
||||
$ret .= '<option value="'.$value.'" '.$attr.'>'.$str.'</option>\n';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getAboWeeksLang($num){
|
||||
if($num == 1){
|
||||
return __('order.every_week');
|
||||
}
|
||||
return __('order.every_weeks', ['num' => $num]);
|
||||
}
|
||||
public static function getAttributesWithoutParents($id = false, $sameId = false, $all = true){
|
||||
$values = Attribute::where('parent_id', null)->get();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('no').'</option>\n';
|
||||
$ret .= '<option value="">'.__('none').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
if($sameId == $value->id){
|
||||
|
|
@ -113,7 +141,7 @@ class HTMLHelper
|
|||
$values = Category::where('parent_id', null)->get();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('no').'</option>\n';
|
||||
$ret .= '<option value="">'.__('none').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
if($sameId == $value->id){
|
||||
|
|
@ -132,7 +160,7 @@ class HTMLHelper
|
|||
$values = Product::where('active', 1)->get();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('no').'</option>\n';
|
||||
$ret .= '<option value="">'.__('none').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
$attr = in_array($value->id, $ids) ? 'selected="selected"' : '';
|
||||
|
|
@ -145,7 +173,7 @@ class HTMLHelper
|
|||
$values = Category::where('active', 1)->orderBy('pos', 'DESC')->get();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('no').'</option>\n';
|
||||
$ret .= '<option value="">'.__('none').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
$attr = in_array($value->id, $ids) ? 'selected="selected"' : '';
|
||||
|
|
@ -170,7 +198,7 @@ class HTMLHelper
|
|||
$values = Attribute::where('active', 1)->get();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('no').'</option>\n';
|
||||
$ret .= '<option value="">'.__('none').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
$attr = in_array($value->id, $ids) ? 'selected="selected"' : '';
|
||||
|
|
@ -183,7 +211,7 @@ class HTMLHelper
|
|||
$values = UserLevel::where('active', 1)->get();
|
||||
$ret = "";
|
||||
if($all){
|
||||
$ret .= '<option value="">'.__('no').'</option>\n';
|
||||
$ret .= '<option value="">'.__('none').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
$attr = ($value->id == $id) ? 'selected="selected"' : '';
|
||||
|
|
@ -303,7 +331,7 @@ class HTMLHelper
|
|||
}
|
||||
|
||||
public static function getTaxSaleOptions($id){
|
||||
$values = array('1' => __('taxable_sales_1'), '2' => __('taxable_sales_2'));
|
||||
$values = array('1' => __('account.taxable_sales_1'), '2' => __('account.taxable_sales_2'));
|
||||
$ret = "";
|
||||
$ret .= '<option value="">'.__('please select').'</option>\n';
|
||||
foreach ($values as $key => $value){
|
||||
|
|
@ -339,7 +367,6 @@ class HTMLHelper
|
|||
$ret .= '<option value="">'.__('please select').'</option>\n';
|
||||
}
|
||||
foreach ($values as $value){
|
||||
dump($value);
|
||||
$attr = ($value->id == $id) ? 'selected="selected"' : '';
|
||||
$to = $value->billing_firstname." ".$value->billing_lastname." | ".$value->billing_email;
|
||||
$ret .= '<option value="'.$value->id.'" '.$attr.'>'.$to.' #'.$value->number.'</option>\n';
|
||||
|
|
|
|||
15
app/Services/IPinfo/.editorconfig
Normal file
15
app/Services/IPinfo/.editorconfig
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
; This file is for unifying the coding style for different editors and IDEs.
|
||||
; More information at http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
42
app/Services/IPinfo/.github/workflows/phpunit.yaml
vendored
Normal file
42
app/Services/IPinfo/.github/workflows/phpunit.yaml
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
name: Unit Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
run:
|
||||
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
matrix:
|
||||
operating-system: [ubuntu-latest]
|
||||
php-versions: ['8.0', '8.1', '8.2']
|
||||
phpunit-versions: ['9.5.20']
|
||||
|
||||
name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
tools: phpunit:${{ matrix.phpunit-versions }}
|
||||
|
||||
- name: Check PHP Version
|
||||
run: php -v
|
||||
|
||||
- name: Validate composer.json and composer.lock
|
||||
run: composer validate --strict
|
||||
|
||||
- name: Composer install
|
||||
run: composer install --optimize-autoloader --prefer-dist --ignore-platform-reqs
|
||||
|
||||
- name: Run test suite
|
||||
env:
|
||||
IPINFO_TOKEN: ${{ secrets.IPINFO_TOKEN }}
|
||||
run: /usr/local/bin/phpunit --coverage-text
|
||||
1
app/Services/IPinfo/.styleci.yml
Normal file
1
app/Services/IPinfo/.styleci.yml
Normal file
|
|
@ -0,0 +1 @@
|
|||
preset: psr2
|
||||
55
app/Services/IPinfo/Details.php
Normal file
55
app/Services/IPinfo/Details.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\IPinfo;
|
||||
|
||||
/**
|
||||
* Holds formatted data for a single IP address.
|
||||
*/
|
||||
class Details
|
||||
{
|
||||
public $country;
|
||||
public $country_name;
|
||||
public $country_flag;
|
||||
public $country_code;
|
||||
public $country_flag_url;
|
||||
public $country_currency;
|
||||
public $continent;
|
||||
public $latitude;
|
||||
public $longitude;
|
||||
public $loc;
|
||||
public $is_eu;
|
||||
public $ip;
|
||||
public $hostname;
|
||||
public $anycast;
|
||||
public $city;
|
||||
public $org;
|
||||
public $postal;
|
||||
public $region;
|
||||
public $timezone;
|
||||
public $asn;
|
||||
public $company;
|
||||
public $privacy;
|
||||
public $abuse;
|
||||
public $domains;
|
||||
public $bogon;
|
||||
public $all;
|
||||
public $error;
|
||||
|
||||
|
||||
public function __construct($raw_details)
|
||||
{
|
||||
foreach ($raw_details as $property => $value) {
|
||||
$this->$property = $value;
|
||||
}
|
||||
$this->all = $raw_details;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns json string representation.
|
||||
*
|
||||
* @internal this class should implement Stringable explicitly when leaving support for PHP verision < 8.0
|
||||
*/
|
||||
public function __toString(): string {
|
||||
return json_encode($this);
|
||||
}
|
||||
}
|
||||
419
app/Services/IPinfo/IPinfo.php
Normal file
419
app/Services/IPinfo/IPinfo.php
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\IPinfo;
|
||||
|
||||
use Exception;
|
||||
use GuzzleHttp\Pool;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Promise;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use App\Services\ipinfo\cache\DefaultCache;
|
||||
use Symfony\Component\HttpFoundation\IpUtils;
|
||||
|
||||
/**
|
||||
* Exposes the IPinfo library to client code.
|
||||
*/
|
||||
class IPinfo
|
||||
{
|
||||
const API_URL = 'https://ipinfo.io';
|
||||
const COUNTRY_FLAG_URL = 'https://cdn.ipinfo.io/static/images/countries-flags/';
|
||||
const STATUS_CODE_QUOTA_EXCEEDED = 429;
|
||||
const REQUEST_TIMEOUT_DEFAULT = 2; // seconds
|
||||
|
||||
const CACHE_MAXSIZE = 4096;
|
||||
const CACHE_TTL = 86400; // 24 hours as seconds
|
||||
const CACHE_KEY_VSN = '1'; // update when cache vals change for same key.
|
||||
|
||||
const COUNTRIES_FILE_DEFAULT = __DIR__ . '/json/countries.json';
|
||||
const COUNTRIES_FLAGS_FILE_DEFAULT = __DIR__ . '/json/flags.json';
|
||||
const EU_COUNTRIES_FILE_DEFAULT = __DIR__ . '/json/eu.json';
|
||||
const COUNTRIES_CURRENCIES_FILE_DEFAULT = __DIR__ . '/json/currency.json';
|
||||
const CONTINENT_FILE_DEFAULT = __DIR__ . '/json/continent.json';
|
||||
|
||||
const BATCH_MAX_SIZE = 1000;
|
||||
const BATCH_TIMEOUT = 5; // seconds
|
||||
|
||||
public $access_token;
|
||||
public $settings;
|
||||
public $cache;
|
||||
public $countries;
|
||||
public $eu_countries;
|
||||
public $countries_flags;
|
||||
public $countries_currencies;
|
||||
public $continents;
|
||||
protected $http_client;
|
||||
|
||||
public function __construct($access_token = null, $settings = [])
|
||||
{
|
||||
$this->access_token = $access_token;
|
||||
$this->settings = $settings;
|
||||
|
||||
/*
|
||||
Support a timeout first-class, then a `guzzle_opts` key that can
|
||||
override anything.
|
||||
*/
|
||||
$guzzle_opts = [
|
||||
'http_errors' => false,
|
||||
'headers' => $this->buildHeaders(),
|
||||
'timeout' => $settings['timeout'] ?? self::REQUEST_TIMEOUT_DEFAULT
|
||||
];
|
||||
if (isset($settings['guzzle_opts'])) {
|
||||
$guzzle_opts = array_merge($guzzle_opts, $settings['guzzle_opts']);
|
||||
}
|
||||
$this->http_client = new Client($guzzle_opts);
|
||||
|
||||
$countries_file = $settings['countries_file'] ?? self::COUNTRIES_FILE_DEFAULT;
|
||||
$countries_flags_file = $settings['countries_flags_file'] ?? self::COUNTRIES_FLAGS_FILE_DEFAULT;
|
||||
$countries_currencies_file = $settings['countries_currencies_file'] ?? self::COUNTRIES_CURRENCIES_FILE_DEFAULT;
|
||||
$eu_countries_file = $settings['eu_countries_file'] ?? self::EU_COUNTRIES_FILE_DEFAULT;
|
||||
$continents_file = $settings['continent_file'] ?? self::CONTINENT_FILE_DEFAULT;
|
||||
$this->countries = $this->readJSONFile($countries_file);
|
||||
$this->countries_flags = $this->readJSONFile($countries_flags_file);
|
||||
$this->countries_currencies = $this->readJSONFile($countries_currencies_file);
|
||||
$this->eu_countries = $this->readJSONFile($eu_countries_file);
|
||||
$this-> continents = $this->readJSONFile($continents_file);
|
||||
|
||||
/*if (!array_key_exists('cache_disabled', $this->settings) || $this->settings['cache_disabled'] == false) {
|
||||
if (array_key_exists('cache', $settings)) {
|
||||
$this->cache = $settings['cache'];
|
||||
} else {
|
||||
$maxsize = $settings['cache_maxsize'] ?? self::CACHE_MAXSIZE;
|
||||
$ttl = $settings['cache_ttl'] ?? self::CACHE_TTL;
|
||||
$this->cache = new DefaultCache($maxsize, $ttl);
|
||||
}
|
||||
} else {
|
||||
$this->cache = null;
|
||||
}*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Get formatted details for an IP address.
|
||||
* @param string|null $ip_address IP address to look up.
|
||||
* @return Details Formatted IPinfo data.
|
||||
* @throws IPinfoException
|
||||
*/
|
||||
public function getDetails($ip_address = null)
|
||||
{
|
||||
$response_details = $this->getRequestDetails((string) $ip_address);
|
||||
return $this->formatDetailsObject($response_details);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get formatted details for a list of IP addresses.
|
||||
* @param $urls the array of URLs.
|
||||
* @param $batchSize default value is set to max value for batch size, which is 1000.
|
||||
* @param batchTimeout in seconds. Default value is 5 seconds.
|
||||
* @param filter default value is false.
|
||||
* @return $results
|
||||
*/
|
||||
public function getBatchDetails(
|
||||
$urls,
|
||||
$batchSize = 0,
|
||||
$batchTimeout = self::BATCH_TIMEOUT,
|
||||
$filter = false
|
||||
) {
|
||||
$lookupUrls = [];
|
||||
$results = [];
|
||||
|
||||
// no items?
|
||||
if (count($urls) == 0) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
// clip batch size.
|
||||
if (!is_numeric($batchSize) || $batchSize <= 0 || $batchSize > self::BATCH_MAX_SIZE) {
|
||||
$batchSize = self::BATCH_MAX_SIZE;
|
||||
}
|
||||
|
||||
// filter out URLs already cached.
|
||||
if ($this->cache != null) {
|
||||
foreach ($urls as $url) {
|
||||
$cachedRes = $this->cache->get($this->cacheKey($url));
|
||||
if ($cachedRes != null) {
|
||||
$results[$url] = $cachedRes;
|
||||
} else {
|
||||
$lookupUrls[] = $url;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$lookupUrls = $urls;
|
||||
}
|
||||
|
||||
// everything cached? exit early.
|
||||
if (count($lookupUrls) == 0) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
// prepare each batch & fire it off asynchronously.
|
||||
$apiUrl = self::API_URL . "/batch";
|
||||
if ($filter) {
|
||||
$apiUrl .= '?filter=1';
|
||||
}
|
||||
$promises = [];
|
||||
$totalBatches = ceil(count($lookupUrls) / $batchSize);
|
||||
for ($i = 0; $i < $totalBatches; $i++) {
|
||||
$start = $i * $batchSize;
|
||||
$batch = array_slice($lookupUrls, $start, $batchSize);
|
||||
$promise = $this->http_client->postAsync($apiUrl, [
|
||||
'body' => json_encode($batch),
|
||||
'timeout' => $batchTimeout
|
||||
])->then(function ($resp) use (&$results) {
|
||||
$batchResult = json_decode($resp->getBody(), true);
|
||||
foreach ($batchResult as $k => $v) {
|
||||
$results[$k] = $v;
|
||||
}
|
||||
});
|
||||
$promises[] = $promise;
|
||||
}
|
||||
|
||||
// wait for all batches to finish.
|
||||
Promise\Utils::settle($promises)->wait();
|
||||
|
||||
// cache any new results.
|
||||
if ($this->cache != null) {
|
||||
foreach ($lookupUrls as $url) {
|
||||
if (array_key_exists($url, $results)) {
|
||||
$this->cache->set($this->cacheKey($url), $results[$url]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function formatDetailsObject($details = [])
|
||||
{
|
||||
$country = $details['country'] ?? null;
|
||||
$details['country_name'] = $this->countries[$country] ?? null;
|
||||
$details['is_eu'] = in_array($country, $this->eu_countries);
|
||||
$details['country_flag'] = $this->countries_flags[$country] ?? null;
|
||||
$details['country_flag_url'] = self::COUNTRY_FLAG_URL.$country.".svg";
|
||||
$details['country_currency'] = $this->countries_currencies[$country] ?? null;
|
||||
$details['continent'] = $this->continents[$country] ?? null;
|
||||
|
||||
if (array_key_exists('loc', $details)) {
|
||||
$coords = explode(',', $details['loc']);
|
||||
$details['latitude'] = $coords[0];
|
||||
$details['longitude'] = $coords[1];
|
||||
} else {
|
||||
$details['latitude'] = null;
|
||||
$details['longitude'] = null;
|
||||
}
|
||||
|
||||
return new Details($details);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get details for a specific IP address.
|
||||
* @param string $ip_address IP address to query API for.
|
||||
* @return array IP response data.
|
||||
* @throws IPinfoException
|
||||
*/
|
||||
public function getRequestDetails(string $ip_address)
|
||||
{
|
||||
if ($this->isBogon($ip_address)) {
|
||||
return [
|
||||
"ip" => $ip_address,
|
||||
"bogon" => true,
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->cache != null) {
|
||||
$cachedRes = $this->cache->get($this->cacheKey($ip_address));
|
||||
if ($cachedRes != null) {
|
||||
return $cachedRes;
|
||||
}
|
||||
}
|
||||
|
||||
$url = self::API_URL;
|
||||
if ($ip_address) {
|
||||
$url .= "/$ip_address";
|
||||
}
|
||||
|
||||
try {
|
||||
$response = $this->http_client->request('GET', $url);
|
||||
} catch (GuzzleException $e) {
|
||||
\Log::channel('ipinfo')->error('IPinfo::getRequestDetails GuzzleException.'. $e->getMessage());
|
||||
return [
|
||||
"ip" => $ip_address,
|
||||
"error" => $e->getMessage(),
|
||||
];
|
||||
//throw new IPinfoException($e->getMessage());
|
||||
} catch (Exception $e) {
|
||||
\Log::channel('ipinfo')->error('IPinfo::getRequestDetails Exception.'. $e->getMessage());
|
||||
return [
|
||||
"ip" => $ip_address,
|
||||
"error" => $e->getMessage(),
|
||||
];
|
||||
//throw new IPinfoException($e->getMessage());
|
||||
}
|
||||
|
||||
if ($response->getStatusCode() == self::STATUS_CODE_QUOTA_EXCEEDED) {
|
||||
//throw new IPinfoException('IPinfo request quota exceeded.');
|
||||
} elseif ($response->getStatusCode() >= 400) {
|
||||
\Log::channel('ipinfo')->error('IPinfo::getRequestDetails getStatusCode.'. json_encode([
|
||||
'status' => $response->getStatusCode(),
|
||||
'reason' => $response->getReasonPhrase(),
|
||||
]));
|
||||
|
||||
return [
|
||||
"ip" => $ip_address,
|
||||
'status' => $response->getStatusCode(),
|
||||
'reason' => $response->getReasonPhrase(),
|
||||
"error" => 'getStatusCode',
|
||||
];
|
||||
/*throw new IPinfoException('Exception: ' . json_encode([
|
||||
'status' => $response->getStatusCode(),
|
||||
'reason' => $response->getReasonPhrase(),
|
||||
]));*/
|
||||
}
|
||||
|
||||
$raw_details = json_decode($response->getBody(), true);
|
||||
|
||||
if ($this->cache != null) {
|
||||
$this->cache->set($this->cacheKey($ip_address), $raw_details);
|
||||
}
|
||||
|
||||
return $raw_details;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a URL to a map on https://ipinfo.io/map given a list of IPs (max
|
||||
* 500,000).
|
||||
* @param array $ips list of IP addresses to put on the map.
|
||||
* @return string URL to the map.
|
||||
*/
|
||||
public function getMapUrl($ips)
|
||||
{
|
||||
$url = sprintf("%s/map?cli=1", self::API_URL);
|
||||
|
||||
try {
|
||||
$response = $this->http_client->request(
|
||||
'POST',
|
||||
$url,
|
||||
[
|
||||
'json' => $ips
|
||||
]
|
||||
);
|
||||
} catch (GuzzleException $e) {
|
||||
throw new IPinfoException($e->getMessage());
|
||||
} catch (Exception $e) {
|
||||
throw new IPinfoException($e->getMessage());
|
||||
}
|
||||
|
||||
$res = json_decode($response->getBody(), true);
|
||||
return $res['reportUrl'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Build headers for API request.
|
||||
* @return array Headers for API request.
|
||||
*/
|
||||
private function buildHeaders()
|
||||
{
|
||||
$headers = [
|
||||
'user-agent' => 'IPinfoClient/PHP/3.1.0',
|
||||
'accept' => 'application/json',
|
||||
'content-type' => 'application/json',
|
||||
];
|
||||
|
||||
if ($this->access_token) {
|
||||
$headers['authorization'] = "Bearer {$this->access_token}";
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read JSON from a file and return as an array.
|
||||
* @param string $countries_file JSON file of country_code => country_name mappings
|
||||
* @return array country_code => country_name mappings
|
||||
*/
|
||||
private function readJSONFile($countries_file)
|
||||
{
|
||||
$file_contents = file_get_contents($countries_file);
|
||||
return json_decode($file_contents, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a versioned cache key given a user-input key.
|
||||
* @param string $k key to transform into a versioned cache key.
|
||||
* @return string the versioned cache key.
|
||||
*/
|
||||
private function cacheKey($k)
|
||||
{
|
||||
return sprintf('%s:%s', $k, self::CACHE_KEY_VSN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an IP address is a bogon.
|
||||
*
|
||||
* @param string $ip The IP address to check
|
||||
* @return bool True if the IP address is a bogon, false otherwise
|
||||
*/
|
||||
public function isBogon($ip)
|
||||
{
|
||||
// Check if the IP address is in the range
|
||||
return IpUtils::checkIp($ip, $this->bogonNetworks);
|
||||
}
|
||||
|
||||
// List of bogon CIDRs.
|
||||
protected $bogonNetworks = [
|
||||
"0.0.0.0/8",
|
||||
"10.0.0.0/8",
|
||||
"100.64.0.0/10",
|
||||
"127.0.0.0/8",
|
||||
"169.254.0.0/16",
|
||||
"172.16.0.0/12",
|
||||
"192.0.0.0/24",
|
||||
"192.0.2.0/24",
|
||||
"192.168.0.0/16",
|
||||
"198.18.0.0/15",
|
||||
"198.51.100.0/24",
|
||||
"203.0.113.0/24",
|
||||
"224.0.0.0/4",
|
||||
"240.0.0.0/4",
|
||||
"255.255.255.255/32",
|
||||
"::/128",
|
||||
"::1/128",
|
||||
"::ffff:0:0/96",
|
||||
"::/96",
|
||||
"100::/64",
|
||||
"2001:10::/28",
|
||||
"2001:db8::/32",
|
||||
"fc00::/7",
|
||||
"fe80::/10",
|
||||
"fec0::/10",
|
||||
"ff00::/8",
|
||||
"2002::/24",
|
||||
"2002:a00::/24",
|
||||
"2002:7f00::/24",
|
||||
"2002:a9fe::/32",
|
||||
"2002:ac10::/28",
|
||||
"2002:c000::/40",
|
||||
"2002:c000:200::/40",
|
||||
"2002:c0a8::/32",
|
||||
"2002:c612::/31",
|
||||
"2002:c633:6400::/40",
|
||||
"2002:cb00:7100::/40",
|
||||
"2002:e000::/20",
|
||||
"2002:f000::/20",
|
||||
"2002:ffff:ffff::/48",
|
||||
"2001::/40",
|
||||
"2001:0:a00::/40",
|
||||
"2001:0:7f00::/40",
|
||||
"2001:0:a9fe::/48",
|
||||
"2001:0:ac10::/44",
|
||||
"2001:0:c000::/56",
|
||||
"2001:0:c000:200::/56",
|
||||
"2001:0:c0a8::/48",
|
||||
"2001:0:c612::/47",
|
||||
"2001:0:c633:6400::/56",
|
||||
"2001:0:cb00:7100::/56",
|
||||
"2001:0:e000::/36",
|
||||
"2001:0:f000::/36",
|
||||
"2001:0:ffff:ffff::/64"
|
||||
];
|
||||
}
|
||||
8
app/Services/IPinfo/IPinfoException.php
Normal file
8
app/Services/IPinfo/IPinfoException.php
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\IPinfo;
|
||||
use Exception;
|
||||
|
||||
class IPinfoException extends Exception
|
||||
{
|
||||
}
|
||||
59
app/Services/IPinfo/_info/CHANGELOG.md
Normal file
59
app/Services/IPinfo/_info/CHANGELOG.md
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# CHANGELOG
|
||||
|
||||
### 3.1.1 (August 3rd 2023)
|
||||
|
||||
- Patched deprecations.
|
||||
|
||||
### 3.1.0 (July 28th 2023)
|
||||
|
||||
- Default cache changed. Replaced `sabre/cache` with `symfony/cache`.
|
||||
|
||||
### 3.0.1 (June 19th 2023)
|
||||
|
||||
- Added the link of country flag image.
|
||||
|
||||
### 3.0.0 (December 27th 2022)
|
||||
|
||||
- Require PHP >= 8.0.
|
||||
- Add local bogon checking.
|
||||
|
||||
### 2.3.1 (June 27 2022)
|
||||
|
||||
- Added Stringable implementation for PHP 8.0 with backward compatibility.
|
||||
|
||||
### 2.3.0 (September 21 2021)
|
||||
|
||||
- Added batch ops integration.
|
||||
- Added the ability to disable cache usage entirely.
|
||||
|
||||
### 2.2.0 (April 22nd 2021)
|
||||
|
||||
- Added Maps integration.
|
||||
- Added versioned cache keys.
|
||||
This allows more reliable changes to cached data in the future without
|
||||
causing confusing incompatibilities. This should be transparent to the user.
|
||||
This is primarily useful for users with persistent cache implementations.
|
||||
|
||||
### 2.1.1 (January 12 2021)
|
||||
|
||||
- Bug fix issue reported in Laravel SDK
|
||||
(https://github.com/ipinfo/laravel/issues/14) which also applies in PHP SDK,
|
||||
with https://github.com/ipinfo/php/pull/27.
|
||||
|
||||
### 2.1.0 (December 2 2020)
|
||||
|
||||
- Deprecate PHP 7.2 support.
|
||||
- Add support for PHP 8.0.
|
||||
|
||||
### 2.0.0 (November 2020)
|
||||
|
||||
- A `guzzle_opts` option is supported in the settings, which allows full Guzzle
|
||||
option overrides.
|
||||
- A `timeout` option is supported in the settings, which is the request timeout
|
||||
value, and defaults to 2 seconds.
|
||||
**BREAKING**: this was previously unconfigurable and was 0 seconds,
|
||||
i.e. infinite timeout.
|
||||
- The `buildHeaders` method on the main `IPinfo` client is now private.
|
||||
**BREAKING**: this will no longer be available for use from the client.
|
||||
- Only non-EOL PHP 7 versions are supported. In particular, PHP 7.2 and above
|
||||
are all supported and tested in the CI.
|
||||
257
app/Services/IPinfo/_info/README.md
Normal file
257
app/Services/IPinfo/_info/README.md
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
# [<img src="https://ipinfo.io/static/ipinfo-small.svg" alt="IPinfo" width="24"/>](https://ipinfo.io/) IPinfo PHP Client Library
|
||||
|
||||
This is the official PHP client library for the [IPinfo.io](https://ipinfo.io) IP address API, allowing you to look up your own IP address, or get any of the following details for an IP:
|
||||
- [IP to Geolocation data](https://ipinfo.io/ip-geolocation-api) (city, region, country, postal code, latitude, and longitude)
|
||||
- [ASN information](https://ipinfo.io/asn-api) (ISP or network operator, associated domain name, and type, such as business, hosting, or company)
|
||||
- [Company details](https://ipinfo.io/ip-company-api) (the name and domain of the business that uses the IP address)
|
||||
- [Carrier information](https://ipinfo.io/ip-carrier-api) (the name of the mobile carrier and MNC and MCC for that carrier if the IP is used exclusively for mobile traffic)
|
||||
|
||||
Check all the data we have for your IP address [here](https://ipinfo.io/what-is-my-ip).
|
||||
|
||||
### Getting Started
|
||||
|
||||
You'll need an IPinfo API access token, which you can get by signing up for a free account at [https://ipinfo.io/signup](https://ipinfo.io/signup?ref=lib-PHP).
|
||||
|
||||
The free plan is limited to 50,000 requests per month, and doesn't include some of the data fields such as IP type and company data. To enable all the data fields and additional request volumes see [https://ipinfo.io/pricing](https://ipinfo.io/pricing?ref=lib-PHP).
|
||||
|
||||
#### Installation
|
||||
|
||||
The package works with PHP 8 and is available using [Composer](https://getcomposer.org).
|
||||
|
||||
```shell
|
||||
composer require ipinfo/ipinfo
|
||||
```
|
||||
|
||||
#### Quick Start
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
use ipinfo\ipinfo\IPinfo;
|
||||
|
||||
$access_token = '123456789abc';
|
||||
$client = new IPinfo($access_token);
|
||||
$ip_address = '216.239.36.21';
|
||||
$details = $client->getDetails($ip_address);
|
||||
|
||||
$details->city; // Emeryville
|
||||
$details->loc; // 37.8342,-122.2900
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
The `IPinfo->getDetails()` method accepts an IP address as an optional, positional argument. If no IP address is specified, the API will return data for the IP address from which it receives the request.
|
||||
|
||||
```php
|
||||
$client = new IPinfo();
|
||||
$ip_address = '216.239.36.21';
|
||||
$details = $client->getDetails($ip_address);
|
||||
$details->city; // Emeryville
|
||||
$details->loc; // 37.8342,-122.2900
|
||||
```
|
||||
|
||||
### Authentication
|
||||
|
||||
The IPinfo library can be authenticated with your IPinfo API token, which is passed in as a positional argument. It also works without an authentication token, but in a more limited capacity.
|
||||
|
||||
```php
|
||||
$access_token = '123456789abc';
|
||||
$client = new IPinfo($access_token);
|
||||
```
|
||||
|
||||
### Details Data
|
||||
|
||||
`IPinfo->getDetails()` will return a `Details` object that contains all fields listed [IPinfo developer docs](https://ipinfo.io/developers/responses#full-response) with a few minor additions. Properties can be accessed directly.
|
||||
|
||||
```php
|
||||
$details->hostname; // cpe-104-175-221-247.socal.res.rr.com
|
||||
```
|
||||
|
||||
#### Country Name
|
||||
|
||||
`Details->country_name` will return the country name, as supplied by the `countries.json` file. See below for instructions on changing that file for use with non-English languages. `Details->country` will still return the country code.
|
||||
|
||||
```php
|
||||
$details->country; // US
|
||||
$details->country_name; // United States
|
||||
```
|
||||
|
||||
#### EU Country
|
||||
|
||||
`Details->is_eu` will return true if the country is a member of the EU, as supplied by the `eu.json` file.
|
||||
|
||||
```php
|
||||
$details->is_eu; // False
|
||||
```
|
||||
|
||||
#### Country Flag
|
||||
|
||||
`Details->country_flag` will return the emoji and Unicode representations of
|
||||
the country's flag, as supplied by the `flags.json` file.
|
||||
|
||||
```php
|
||||
$details->country_flag['emoji']; // 🇺🇸
|
||||
$details->country_flag['unicode']; // U+1F1FA U+1F1F8
|
||||
```
|
||||
|
||||
#### Country Flag URL
|
||||
|
||||
`Details->country_flag_url` will return a public link to the country's flag image as an SVG which can be used anywhere.
|
||||
|
||||
```php
|
||||
$details->country_flag_url; // https://cdn.ipinfo.io/static/images/countries-flags/US.svg
|
||||
```
|
||||
|
||||
#### Country Currency
|
||||
|
||||
`Details->country_currency` will return the code and symbol of the
|
||||
country's currency, as supplied by the `currency.json` file.
|
||||
|
||||
```php
|
||||
$details->country_currency['code']; // USD
|
||||
$details->country_currency['symbol']; // $
|
||||
```
|
||||
|
||||
#### Continent
|
||||
|
||||
`Details->continent` will return the code and name of the
|
||||
continent, as supplied by the `continent.json` file.
|
||||
|
||||
```php
|
||||
$details->continent['code']; // NA
|
||||
$details->continent['name']; // North America
|
||||
```
|
||||
|
||||
#### Longitude and Latitude
|
||||
|
||||
`Details->latitude` and `Details->longitude` will return latitude and longitude, respectively, as strings. `Details->loc` will still return a composite string of both values.
|
||||
|
||||
```php
|
||||
$details->loc; // 34.0293,-118.3570
|
||||
$details->latitude; // 34.0293
|
||||
$details->longitude; // -118.3570
|
||||
```
|
||||
|
||||
#### Accessing all properties
|
||||
|
||||
`Details->all` will return all details data as a dictionary.
|
||||
|
||||
```php
|
||||
$details->all;
|
||||
/*
|
||||
{
|
||||
'asn': { 'asn': 'AS20001',
|
||||
'domain': 'twcable.com',
|
||||
'name': 'Time Warner Cable Internet LLC',
|
||||
'route': '104.172.0.0/14',
|
||||
'type': 'isp'},
|
||||
'city': 'Los Angeles',
|
||||
'company': { 'domain': 'twcable.com',
|
||||
'name': 'Time Warner Cable Internet LLC',
|
||||
'type': 'isp'},
|
||||
'country': 'US',
|
||||
'country_name': 'United States',
|
||||
'hostname': 'cpe-104-175-221-247.socal.res.rr.com',
|
||||
'ip': '104.175.221.247',
|
||||
'loc': '34.0293,-118.3570',
|
||||
'latitude': '34.0293',
|
||||
'longitude': '-118.3570',
|
||||
'phone': '323',
|
||||
'postal': '90016',
|
||||
'region': 'California'
|
||||
}
|
||||
*/
|
||||
```
|
||||
|
||||
### Caching
|
||||
|
||||
In-memory caching of `Details` data is provided by default via the [symfony/cache](https://github.com/symfony/cache/) library. LRU (least recently used) cache-invalidation functionality has been added to the default TTL (time to live). This means that values will be cached for the specified duration; if the cache's max size is reached, cache values will be invalidated as necessary, starting with the oldest cached value.
|
||||
|
||||
#### Modifying cache options
|
||||
|
||||
Default cache TTL and maximum size can be changed by setting values in the `$settings` argument array.
|
||||
|
||||
* Default maximum cache size: 4096 (multiples of 2 are recommended to increase efficiency)
|
||||
* Default TTL: 24 hours (in seconds)
|
||||
|
||||
```php
|
||||
$access_token = '123456789abc';
|
||||
$settings = ['cache_maxsize' => 30, 'cache_ttl' => 128];
|
||||
$client = new IPinfo($access_token, $settings);
|
||||
```
|
||||
|
||||
#### Using a different cache
|
||||
|
||||
It's possible to use a custom cache by creating a child class of the [CacheInterface](https://github.com/ipinfo/php/blob/master/src/cache/Interface.php) class and passing this into the handler object with the `cache` keyword argument. FYI this is known as [the Strategy Pattern](https://sourcemaking.com/design_patterns/strategy).
|
||||
|
||||
```php
|
||||
$access_token = '123456789abc';
|
||||
$settings = ['cache' => $my_fancy_custom_cache];
|
||||
$client = new IPinfo($access_token, $settings);
|
||||
```
|
||||
|
||||
#### Disabling the cache
|
||||
|
||||
You may disable the cache by passing in a `cache_disabled` key in the settings:
|
||||
|
||||
```php
|
||||
$access_token = '123456789abc';
|
||||
$settings = ['cache_disabled' => true];
|
||||
$client = new IPinfo($access_token, $settings);
|
||||
```
|
||||
|
||||
### Overriding HTTP Client options
|
||||
|
||||
The IPinfo client constructor accepts a `timeout` key which is the request
|
||||
timeout in seconds.
|
||||
|
||||
For full flexibility, a `guzzle_opts` key is accepted which accepts an
|
||||
associative array which is described in [Guzzle Request Options](https://docs.guzzlephp.org/en/stable/request-options.html).
|
||||
Options set here will override any custom settings set by the IPinfo client
|
||||
internally in case of conflict, including headers.
|
||||
|
||||
### Batch Operations
|
||||
|
||||
Looking up a single IP at a time can be slow. It could be done concurrently from the client side, but IPinfo supports a batch endpoint to allow you to group together IPs and let us handle retrieving details for them in bulk for you.
|
||||
|
||||
```php
|
||||
$access_token = '123456789abc';
|
||||
$client = new IPinfo($access_token);
|
||||
$ips = ['1.1.1.1', '8.8.8.8', '1.2.3.4/country'];
|
||||
$results = $client->getBatchDetails($ips);
|
||||
echo $results['1.2.3.4/country']; // AU
|
||||
var_dump($results['1.1.1.1']);
|
||||
var_dump($results['8.8.8.8']);
|
||||
```
|
||||
|
||||
The input size is not limited, as the interface will chunk operations for you behind the scenes.
|
||||
|
||||
Please see [the official documentation](https://ipinfo.io/developers/batch) for more information and limitations.
|
||||
|
||||
### Internationalization
|
||||
|
||||
When looking up an IP address, the response object includes a `Details->country_name` attribute which includes the country name based on American English. It is possible to return the country name in other languages by setting the `countries_file` keyword argument when creating the `IPinfo` object.
|
||||
|
||||
The file must be a `.json` file with the following structure:
|
||||
|
||||
```JSON
|
||||
{
|
||||
"BD": "Bangladesh",
|
||||
"BE": "Belgium",
|
||||
"BF": "Burkina Faso",
|
||||
"BG": "Bulgaria"
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Other Libraries
|
||||
|
||||
There are official IPinfo client libraries available for many languages including PHP, Python, Go, Java, Ruby, and many popular frameworks such as Django, Rails, and Laravel. There are also many third-party libraries and integrations available for our API.
|
||||
|
||||
### About IPinfo
|
||||
|
||||
Founded in 2013, IPinfo prides itself on being the most reliable, accurate, and in-depth source of IP address data available anywhere. We process terabytes of data to produce our custom IP geolocation, company, carrier, privacy, hosted domains and IP type data sets. Our API handles over 40 billion requests a month for 100,000 businesses and developers.
|
||||
|
||||
[](https://ipinfo.io/)
|
||||
64
app/Services/IPinfo/_info/composer.json
Normal file
64
app/Services/IPinfo/_info/composer.json
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"name": "ipinfo/ipinfo",
|
||||
"type": "library",
|
||||
"description": "The official PHP library for IPinfo, the most reliable, accurate, and in-depth source of IP address data available anywhere. We process terabytes of data to produce our custom IP geolocation, company, carrier and IP type data sets. Visit our developer docs at https://ipinfo.io/developers.",
|
||||
"keywords": [
|
||||
"ipinfo"
|
||||
],
|
||||
"homepage": "https://github.com/ipinfo/php",
|
||||
"license": "Apache-2.0",
|
||||
"authors": [
|
||||
{
|
||||
"name": "James Timmins",
|
||||
"email": "jameshtimmins@gmail.com",
|
||||
"homepage": "https://github.com/jhtimmins",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Uman Shahzad",
|
||||
"email": "uman@mslm.io",
|
||||
"homepage": "https://github.com/UmanShahzad",
|
||||
"role": "Developer"
|
||||
},
|
||||
{
|
||||
"name": "Umar Farooq",
|
||||
"email": "umar@ipinfo.io",
|
||||
"homepage": "https://github.com/rm-Umar",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/guzzle": "^6.3||^7.0",
|
||||
"symfony/cache": "^6.3",
|
||||
"symfony/http-foundation": "^6.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^10.0.0",
|
||||
"squizlabs/php_codesniffer": "^3.5.8"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ipinfo\\ipinfo\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"ipinfo\\ipinfo\\": "tests"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit",
|
||||
"check-style": "phpcs -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src tests",
|
||||
"fix-style": "phpcbf -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src tests"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.1.1-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
31
app/Services/IPinfo/cache/CacheInterface.php
vendored
Normal file
31
app/Services/IPinfo/cache/CacheInterface.php
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\IPinfo\cache;
|
||||
|
||||
/**
|
||||
* Interface for caches used to store IP data between requests.
|
||||
*/
|
||||
interface CacheInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Tests if the specified IP address is cached.
|
||||
* @param string $ip_address IP address to lookup.
|
||||
* @return boolean Is the IP address data in the cache.
|
||||
*/
|
||||
public function has(string $ip_address);
|
||||
|
||||
/**
|
||||
* Set the IP address key to the specified value.
|
||||
* @param string $ip_address IP address to cache data for.
|
||||
* @param mixed $value Data for specified IP address.
|
||||
*/
|
||||
public function set(string $ip_address, $value);
|
||||
|
||||
/**
|
||||
* Get data for the specified IP address.
|
||||
* @param string $ip_address IP address to lookup in cache.
|
||||
* @return mixed IP address data.
|
||||
*/
|
||||
public function get(string $ip_address);
|
||||
}
|
||||
82
app/Services/IPinfo/cache/DefaultCache.php
vendored
Normal file
82
app/Services/IPinfo/cache/DefaultCache.php
vendored
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
namespace App\Services\IPinfo\cache;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
|
||||
/**
|
||||
* Default implementation of the CacheInterface. Provides in-memory caching.
|
||||
*/
|
||||
class DefaultCache implements CacheInterface
|
||||
{
|
||||
|
||||
public $maxsize;
|
||||
public $ttl;
|
||||
|
||||
private $cache;
|
||||
private $element_queue;
|
||||
|
||||
public function __construct(int $maxsize, int $ttl)
|
||||
{
|
||||
$this->cache = new ArrayAdapter();
|
||||
$this->element_queue = array();
|
||||
$this->maxsize = $maxsize;
|
||||
$this->ttl = $ttl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the specified IP address is cached.
|
||||
* @param string $ip_address IP address to lookup.
|
||||
* @return boolean Is the IP address data in the cache.
|
||||
*/
|
||||
public function has(string $name): bool
|
||||
{
|
||||
return $this->cache->hasItem($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the IP address key to the specified value.
|
||||
* @param string $ip_address IP address to cache data for.
|
||||
* @param mixed $value Data for specified IP address.
|
||||
*/
|
||||
public function set(string $name, $value)
|
||||
{
|
||||
if (!$this->cache->hasItem($name)) {
|
||||
$this->element_queue[] = $name;
|
||||
}
|
||||
|
||||
$this->cache->get($name, function (ItemInterface $item) use ($value) {
|
||||
$item->set($value)->expiresAfter($this->ttl);
|
||||
return $item->get();
|
||||
});
|
||||
|
||||
$this->manageSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data for the specified IP address.
|
||||
* @param string $ip_address IP address to lookup in cache.
|
||||
* @return mixed IP address data.
|
||||
*/
|
||||
public function get(string $name)
|
||||
{
|
||||
return $this->cache->getItem($name)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* If cache maxsize has been reached, remove oldest elements until limit is reached.
|
||||
*/
|
||||
private function manageSize()
|
||||
{
|
||||
$overflow = count($this->element_queue) - $this->maxsize;
|
||||
if ($overflow > 0) {
|
||||
foreach (array_slice($this->element_queue, 0, $overflow) as $name) {
|
||||
if ($this->has($name)) {
|
||||
$this->cache->delete($name);
|
||||
}
|
||||
}
|
||||
$this->element_queue = array_slice($this->element_queue, $overflow);
|
||||
}
|
||||
}
|
||||
}
|
||||
252
app/Services/IPinfo/json/continent.json
Normal file
252
app/Services/IPinfo/json/continent.json
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
{
|
||||
"BD": {"code": "AS", "name": "Asia"},
|
||||
"BE": {"code": "EU", "name": "Europe"},
|
||||
"BF": {"code": "AF", "name": "Africa"},
|
||||
"BG": {"code": "EU", "name": "Europe"},
|
||||
"BA": {"code": "EU", "name": "Europe"},
|
||||
"BB": {"code": "NA", "name": "North America"},
|
||||
"WF": {"code": "OC", "name": "Oceania"},
|
||||
"BL": {"code": "NA", "name": "North America"},
|
||||
"BM": {"code": "NA", "name": "North America"},
|
||||
"BN": {"code": "AS", "name": "Asia"},
|
||||
"BO": {"code": "SA", "name": "South America"},
|
||||
"BH": {"code": "AS", "name": "Asia"},
|
||||
"BI": {"code": "AF", "name": "Africa"},
|
||||
"BJ": {"code": "AF", "name": "Africa"},
|
||||
"BT": {"code": "AS", "name": "Asia"},
|
||||
"JM": {"code": "NA", "name": "North America"},
|
||||
"BV": {"code": "AN", "name": "Antarctica"},
|
||||
"BW": {"code": "AF", "name": "Africa"},
|
||||
"WS": {"code": "OC", "name": "Oceania"},
|
||||
"BQ": {"code": "NA", "name": "North America"},
|
||||
"BR": {"code": "SA", "name": "South America"},
|
||||
"BS": {"code": "NA", "name": "North America"},
|
||||
"JE": {"code": "EU", "name": "Europe"},
|
||||
"BY": {"code": "EU", "name": "Europe"},
|
||||
"BZ": {"code": "NA", "name": "North America"},
|
||||
"RU": {"code": "EU", "name": "Europe"},
|
||||
"RW": {"code": "AF", "name": "Africa"},
|
||||
"RS": {"code": "EU", "name": "Europe"},
|
||||
"TL": {"code": "OC", "name": "Oceania"},
|
||||
"RE": {"code": "AF", "name": "Africa"},
|
||||
"TM": {"code": "AS", "name": "Asia"},
|
||||
"TJ": {"code": "AS", "name": "Asia"},
|
||||
"RO": {"code": "EU", "name": "Europe"},
|
||||
"TK": {"code": "OC", "name": "Oceania"},
|
||||
"GW": {"code": "AF", "name": "Africa"},
|
||||
"GU": {"code": "OC", "name": "Oceania"},
|
||||
"GT": {"code": "NA", "name": "North America"},
|
||||
"GS": {"code": "AN", "name": "Antarctica"},
|
||||
"GR": {"code": "EU", "name": "Europe"},
|
||||
"GQ": {"code": "AF", "name": "Africa"},
|
||||
"GP": {"code": "NA", "name": "North America"},
|
||||
"JP": {"code": "AS", "name": "Asia"},
|
||||
"GY": {"code": "SA", "name": "South America"},
|
||||
"GG": {"code": "EU", "name": "Europe"},
|
||||
"GF": {"code": "SA", "name": "South America"},
|
||||
"GE": {"code": "AS", "name": "Asia"},
|
||||
"GD": {"code": "NA", "name": "North America"},
|
||||
"GB": {"code": "EU", "name": "Europe"},
|
||||
"GA": {"code": "AF", "name": "Africa"},
|
||||
"SV": {"code": "NA", "name": "North America"},
|
||||
"GN": {"code": "AF", "name": "Africa"},
|
||||
"GM": {"code": "AF", "name": "Africa"},
|
||||
"GL": {"code": "NA", "name": "North America"},
|
||||
"GI": {"code": "EU", "name": "Europe"},
|
||||
"GH": {"code": "AF", "name": "Africa"},
|
||||
"OM": {"code": "AS", "name": "Asia"},
|
||||
"TN": {"code": "AF", "name": "Africa"},
|
||||
"JO": {"code": "AS", "name": "Asia"},
|
||||
"HR": {"code": "EU", "name": "Europe"},
|
||||
"HT": {"code": "NA", "name": "North America"},
|
||||
"HU": {"code": "EU", "name": "Europe"},
|
||||
"HK": {"code": "AS", "name": "Asia"},
|
||||
"HN": {"code": "NA", "name": "North America"},
|
||||
"HM": {"code": "AN", "name": "Antarctica"},
|
||||
"VE": {"code": "SA", "name": "South America"},
|
||||
"PR": {"code": "NA", "name": "North America"},
|
||||
"PS": {"code": "AS", "name": "Asia"},
|
||||
"PW": {"code": "OC", "name": "Oceania"},
|
||||
"PT": {"code": "EU", "name": "Europe"},
|
||||
"SJ": {"code": "EU", "name": "Europe"},
|
||||
"PY": {"code": "SA", "name": "South America"},
|
||||
"IQ": {"code": "AS", "name": "Asia"},
|
||||
"PA": {"code": "NA", "name": "North America"},
|
||||
"PF": {"code": "OC", "name": "Oceania"},
|
||||
"PG": {"code": "OC", "name": "Oceania"},
|
||||
"PE": {"code": "SA", "name": "South America"},
|
||||
"PK": {"code": "AS", "name": "Asia"},
|
||||
"PH": {"code": "AS", "name": "Asia"},
|
||||
"PN": {"code": "OC", "name": "Oceania"},
|
||||
"PL": {"code": "EU", "name": "Europe"},
|
||||
"PM": {"code": "NA", "name": "North America"},
|
||||
"ZM": {"code": "AF", "name": "Africa"},
|
||||
"EH": {"code": "AF", "name": "Africa"},
|
||||
"EE": {"code": "EU", "name": "Europe"},
|
||||
"EG": {"code": "AF", "name": "Africa"},
|
||||
"ZA": {"code": "AF", "name": "Africa"},
|
||||
"EC": {"code": "SA", "name": "South America"},
|
||||
"IT": {"code": "EU", "name": "Europe"},
|
||||
"VN": {"code": "AS", "name": "Asia"},
|
||||
"SB": {"code": "OC", "name": "Oceania"},
|
||||
"ET": {"code": "AF", "name": "Africa"},
|
||||
"SO": {"code": "AF", "name": "Africa"},
|
||||
"ZW": {"code": "AF", "name": "Africa"},
|
||||
"SA": {"code": "AS", "name": "Asia"},
|
||||
"ES": {"code": "EU", "name": "Europe"},
|
||||
"ER": {"code": "AF", "name": "Africa"},
|
||||
"ME": {"code": "EU", "name": "Europe"},
|
||||
"MD": {"code": "EU", "name": "Europe"},
|
||||
"MG": {"code": "AF", "name": "Africa"},
|
||||
"MF": {"code": "NA", "name": "North America"},
|
||||
"MA": {"code": "AF", "name": "Africa"},
|
||||
"MC": {"code": "EU", "name": "Europe"},
|
||||
"UZ": {"code": "AS", "name": "Asia"},
|
||||
"MM": {"code": "AS", "name": "Asia"},
|
||||
"ML": {"code": "AF", "name": "Africa"},
|
||||
"MO": {"code": "AS", "name": "Asia"},
|
||||
"MN": {"code": "AS", "name": "Asia"},
|
||||
"MH": {"code": "OC", "name": "Oceania"},
|
||||
"MK": {"code": "EU", "name": "Europe"},
|
||||
"MU": {"code": "AF", "name": "Africa"},
|
||||
"MT": {"code": "EU", "name": "Europe"},
|
||||
"MW": {"code": "AF", "name": "Africa"},
|
||||
"MV": {"code": "AS", "name": "Asia"},
|
||||
"MQ": {"code": "NA", "name": "North America"},
|
||||
"MP": {"code": "OC", "name": "Oceania"},
|
||||
"MS": {"code": "NA", "name": "North America"},
|
||||
"MR": {"code": "AF", "name": "Africa"},
|
||||
"IM": {"code": "EU", "name": "Europe"},
|
||||
"UG": {"code": "AF", "name": "Africa"},
|
||||
"TZ": {"code": "AF", "name": "Africa"},
|
||||
"MY": {"code": "AS", "name": "Asia"},
|
||||
"MX": {"code": "NA", "name": "North America"},
|
||||
"IL": {"code": "AS", "name": "Asia"},
|
||||
"FR": {"code": "EU", "name": "Europe"},
|
||||
"IO": {"code": "AS", "name": "Asia"},
|
||||
"SH": {"code": "AF", "name": "Africa"},
|
||||
"FI": {"code": "EU", "name": "Europe"},
|
||||
"FJ": {"code": "OC", "name": "Oceania"},
|
||||
"FK": {"code": "SA", "name": "South America"},
|
||||
"FM": {"code": "OC", "name": "Oceania"},
|
||||
"FO": {"code": "EU", "name": "Europe"},
|
||||
"NI": {"code": "NA", "name": "North America"},
|
||||
"NL": {"code": "EU", "name": "Europe"},
|
||||
"NO": {"code": "EU", "name": "Europe"},
|
||||
"NA": {"code": "AF", "name": "Africa"},
|
||||
"VU": {"code": "OC", "name": "Oceania"},
|
||||
"NC": {"code": "OC", "name": "Oceania"},
|
||||
"NE": {"code": "AF", "name": "Africa"},
|
||||
"NF": {"code": "OC", "name": "Oceania"},
|
||||
"NG": {"code": "AF", "name": "Africa"},
|
||||
"NZ": {"code": "OC", "name": "Oceania"},
|
||||
"NP": {"code": "AS", "name": "Asia"},
|
||||
"NR": {"code": "OC", "name": "Oceania"},
|
||||
"NU": {"code": "OC", "name": "Oceania"},
|
||||
"CK": {"code": "OC", "name": "Oceania"},
|
||||
"XK": {"code": "EU", "name": "Europe"},
|
||||
"CI": {"code": "AF", "name": "Africa"},
|
||||
"CH": {"code": "EU", "name": "Europe"},
|
||||
"CO": {"code": "SA", "name": "South America"},
|
||||
"CN": {"code": "AS", "name": "Asia"},
|
||||
"CM": {"code": "AF", "name": "Africa"},
|
||||
"CL": {"code": "SA", "name": "South America"},
|
||||
"CC": {"code": "AS", "name": "Asia"},
|
||||
"CA": {"code": "NA", "name": "North America"},
|
||||
"CG": {"code": "AF", "name": "Africa"},
|
||||
"CF": {"code": "AF", "name": "Africa"},
|
||||
"CD": {"code": "AF", "name": "Africa"},
|
||||
"CZ": {"code": "EU", "name": "Europe"},
|
||||
"CY": {"code": "EU", "name": "Europe"},
|
||||
"CX": {"code": "AS", "name": "Asia"},
|
||||
"CR": {"code": "NA", "name": "North America"},
|
||||
"CW": {"code": "NA", "name": "North America"},
|
||||
"CV": {"code": "AF", "name": "Africa"},
|
||||
"CU": {"code": "NA", "name": "North America"},
|
||||
"SZ": {"code": "AF", "name": "Africa"},
|
||||
"SY": {"code": "AS", "name": "Asia"},
|
||||
"SX": {"code": "NA", "name": "North America"},
|
||||
"KG": {"code": "AS", "name": "Asia"},
|
||||
"KE": {"code": "AF", "name": "Africa"},
|
||||
"SS": {"code": "AF", "name": "Africa"},
|
||||
"SR": {"code": "SA", "name": "South America"},
|
||||
"KI": {"code": "OC", "name": "Oceania"},
|
||||
"KH": {"code": "AS", "name": "Asia"},
|
||||
"KN": {"code": "NA", "name": "North America"},
|
||||
"KM": {"code": "AF", "name": "Africa"},
|
||||
"ST": {"code": "AF", "name": "Africa"},
|
||||
"SK": {"code": "EU", "name": "Europe"},
|
||||
"KR": {"code": "AS", "name": "Asia"},
|
||||
"SI": {"code": "EU", "name": "Europe"},
|
||||
"KP": {"code": "AS", "name": "Asia"},
|
||||
"KW": {"code": "AS", "name": "Asia"},
|
||||
"SN": {"code": "AF", "name": "Africa"},
|
||||
"SM": {"code": "EU", "name": "Europe"},
|
||||
"SL": {"code": "AF", "name": "Africa"},
|
||||
"SC": {"code": "AF", "name": "Africa"},
|
||||
"KZ": {"code": "AS", "name": "Asia"},
|
||||
"KY": {"code": "NA", "name": "North America"},
|
||||
"SG": {"code": "AS", "name": "Asia"},
|
||||
"SE": {"code": "EU", "name": "Europe"},
|
||||
"SD": {"code": "AF", "name": "Africa"},
|
||||
"DO": {"code": "NA", "name": "North America"},
|
||||
"DM": {"code": "NA", "name": "North America"},
|
||||
"DJ": {"code": "AF", "name": "Africa"},
|
||||
"DK": {"code": "EU", "name": "Europe"},
|
||||
"VG": {"code": "NA", "name": "North America"},
|
||||
"DE": {"code": "EU", "name": "Europe"},
|
||||
"YE": {"code": "AS", "name": "Asia"},
|
||||
"DZ": {"code": "AF", "name": "Africa"},
|
||||
"US": {"code": "NA", "name": "North America"},
|
||||
"UY": {"code": "SA", "name": "South America"},
|
||||
"YT": {"code": "AF", "name": "Africa"},
|
||||
"UM": {"code": "OC", "name": "Oceania"},
|
||||
"LB": {"code": "AS", "name": "Asia"},
|
||||
"LC": {"code": "NA", "name": "North America"},
|
||||
"LA": {"code": "AS", "name": "Asia"},
|
||||
"TV": {"code": "OC", "name": "Oceania"},
|
||||
"TW": {"code": "AS", "name": "Asia"},
|
||||
"TT": {"code": "NA", "name": "North America"},
|
||||
"TR": {"code": "AS", "name": "Asia"},
|
||||
"LK": {"code": "AS", "name": "Asia"},
|
||||
"LI": {"code": "EU", "name": "Europe"},
|
||||
"LV": {"code": "EU", "name": "Europe"},
|
||||
"TO": {"code": "OC", "name": "Oceania"},
|
||||
"LT": {"code": "EU", "name": "Europe"},
|
||||
"LU": {"code": "EU", "name": "Europe"},
|
||||
"LR": {"code": "AF", "name": "Africa"},
|
||||
"LS": {"code": "AF", "name": "Africa"},
|
||||
"TH": {"code": "AS", "name": "Asia"},
|
||||
"TF": {"code": "AN", "name": "Antarctica"},
|
||||
"TG": {"code": "AF", "name": "Africa"},
|
||||
"TD": {"code": "AF", "name": "Africa"},
|
||||
"TC": {"code": "NA", "name": "North America"},
|
||||
"LY": {"code": "AF", "name": "Africa"},
|
||||
"VA": {"code": "EU", "name": "Europe"},
|
||||
"VC": {"code": "NA", "name": "North America"},
|
||||
"AE": {"code": "AS", "name": "Asia"},
|
||||
"AD": {"code": "EU", "name": "Europe"},
|
||||
"AG": {"code": "NA", "name": "North America"},
|
||||
"AF": {"code": "AS", "name": "Asia"},
|
||||
"AI": {"code": "NA", "name": "North America"},
|
||||
"VI": {"code": "NA", "name": "North America"},
|
||||
"IS": {"code": "EU", "name": "Europe"},
|
||||
"IR": {"code": "AS", "name": "Asia"},
|
||||
"AM": {"code": "AS", "name": "Asia"},
|
||||
"AL": {"code": "EU", "name": "Europe"},
|
||||
"AO": {"code": "AF", "name": "Africa"},
|
||||
"AQ": {"code": "AN", "name": "Antarctica"},
|
||||
"AS": {"code": "OC", "name": "Oceania"},
|
||||
"AR": {"code": "SA", "name": "South America"},
|
||||
"AU": {"code": "OC", "name": "Oceania"},
|
||||
"AT": {"code": "EU", "name": "Europe"},
|
||||
"AW": {"code": "NA", "name": "North America"},
|
||||
"IN": {"code": "AS", "name": "Asia"},
|
||||
"AX": {"code": "EU", "name": "Europe"},
|
||||
"AZ": {"code": "AS", "name": "Asia"},
|
||||
"IE": {"code": "EU", "name": "Europe"},
|
||||
"ID": {"code": "AS", "name": "Asia"},
|
||||
"UA": {"code": "EU", "name": "Europe"},
|
||||
"QA": {"code": "AS", "name": "Asia"},
|
||||
"MZ": {"code": "AF", "name": "Africa"}
|
||||
}
|
||||
1
app/Services/IPinfo/json/countries.json
Normal file
1
app/Services/IPinfo/json/countries.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"BD": "Bangladesh", "BE": "Belgium", "BF": "Burkina Faso", "BG": "Bulgaria", "BA": "Bosnia and Herzegovina", "BB": "Barbados", "WF": "Wallis and Futuna", "BL": "Saint Barthelemy", "BM": "Bermuda", "BN": "Brunei", "BO": "Bolivia", "BH": "Bahrain", "BI": "Burundi", "BJ": "Benin", "BT": "Bhutan", "JM": "Jamaica", "BV": "Bouvet Island", "BW": "Botswana", "WS": "Samoa", "BQ": "Bonaire, Saint Eustatius and Saba ", "BR": "Brazil", "BS": "Bahamas", "JE": "Jersey", "BY": "Belarus", "BZ": "Belize", "RU": "Russia", "RW": "Rwanda", "RS": "Serbia", "TL": "East Timor", "RE": "Reunion", "TM": "Turkmenistan", "TJ": "Tajikistan", "RO": "Romania", "TK": "Tokelau", "GW": "Guinea-Bissau", "GU": "Guam", "GT": "Guatemala", "GS": "South Georgia and the South Sandwich Islands", "GR": "Greece", "GQ": "Equatorial Guinea", "GP": "Guadeloupe", "JP": "Japan", "GY": "Guyana", "GG": "Guernsey", "GF": "French Guiana", "GE": "Georgia", "GD": "Grenada", "GB": "United Kingdom", "GA": "Gabon", "SV": "El Salvador", "GN": "Guinea", "GM": "Gambia", "GL": "Greenland", "GI": "Gibraltar", "GH": "Ghana", "OM": "Oman", "TN": "Tunisia", "JO": "Jordan", "HR": "Croatia", "HT": "Haiti", "HU": "Hungary", "HK": "Hong Kong", "HN": "Honduras", "HM": "Heard Island and McDonald Islands", "VE": "Venezuela", "PR": "Puerto Rico", "PS": "Palestinian Territory", "PW": "Palau", "PT": "Portugal", "SJ": "Svalbard and Jan Mayen", "PY": "Paraguay", "IQ": "Iraq", "PA": "Panama", "PF": "French Polynesia", "PG": "Papua New Guinea", "PE": "Peru", "PK": "Pakistan", "PH": "Philippines", "PN": "Pitcairn", "PL": "Poland", "PM": "Saint Pierre and Miquelon", "ZM": "Zambia", "EH": "Western Sahara", "EE": "Estonia", "EG": "Egypt", "ZA": "South Africa", "EC": "Ecuador", "IT": "Italy", "VN": "Vietnam", "SB": "Solomon Islands", "ET": "Ethiopia", "SO": "Somalia", "ZW": "Zimbabwe", "SA": "Saudi Arabia", "ES": "Spain", "ER": "Eritrea", "ME": "Montenegro", "MD": "Moldova", "MG": "Madagascar", "MF": "Saint Martin", "MA": "Morocco", "MC": "Monaco", "UZ": "Uzbekistan", "MM": "Myanmar", "ML": "Mali", "MO": "Macao", "MN": "Mongolia", "MH": "Marshall Islands", "MK": "Macedonia", "MU": "Mauritius", "MT": "Malta", "MW": "Malawi", "MV": "Maldives", "MQ": "Martinique", "MP": "Northern Mariana Islands", "MS": "Montserrat", "MR": "Mauritania", "IM": "Isle of Man", "UG": "Uganda", "TZ": "Tanzania", "MY": "Malaysia", "MX": "Mexico", "IL": "Israel", "FR": "France", "IO": "British Indian Ocean Territory", "SH": "Saint Helena", "FI": "Finland", "FJ": "Fiji", "FK": "Falkland Islands", "FM": "Micronesia", "FO": "Faroe Islands", "NI": "Nicaragua", "NL": "Netherlands", "NO": "Norway", "NA": "Namibia", "VU": "Vanuatu", "NC": "New Caledonia", "NE": "Niger", "NF": "Norfolk Island", "NG": "Nigeria", "NZ": "New Zealand", "NP": "Nepal", "NR": "Nauru", "NU": "Niue", "CK": "Cook Islands", "XK": "Kosovo", "CI": "Ivory Coast", "CH": "Switzerland", "CO": "Colombia", "CN": "China", "CM": "Cameroon", "CL": "Chile", "CC": "Cocos Islands", "CA": "Canada", "CG": "Republic of the Congo", "CF": "Central African Republic", "CD": "Democratic Republic of the Congo", "CZ": "Czech Republic", "CY": "Cyprus", "CX": "Christmas Island", "CR": "Costa Rica", "CW": "Curacao", "CV": "Cape Verde", "CU": "Cuba", "SZ": "Swaziland", "SY": "Syria", "SX": "Sint Maarten", "KG": "Kyrgyzstan", "KE": "Kenya", "SS": "South Sudan", "SR": "Suriname", "KI": "Kiribati", "KH": "Cambodia", "KN": "Saint Kitts and Nevis", "KM": "Comoros", "ST": "Sao Tome and Principe", "SK": "Slovakia", "KR": "South Korea", "SI": "Slovenia", "KP": "North Korea", "KW": "Kuwait", "SN": "Senegal", "SM": "San Marino", "SL": "Sierra Leone", "SC": "Seychelles", "KZ": "Kazakhstan", "KY": "Cayman Islands", "SG": "Singapore", "SE": "Sweden", "SD": "Sudan", "DO": "Dominican Republic", "DM": "Dominica", "DJ": "Djibouti", "DK": "Denmark", "VG": "British Virgin Islands", "DE": "Germany", "YE": "Yemen", "DZ": "Algeria", "US": "United States", "UY": "Uruguay", "YT": "Mayotte", "UM": "United States Minor Outlying Islands", "LB": "Lebanon", "LC": "Saint Lucia", "LA": "Laos", "TV": "Tuvalu", "TW": "Taiwan", "TT": "Trinidad and Tobago", "TR": "Turkey", "LK": "Sri Lanka", "LI": "Liechtenstein", "LV": "Latvia", "TO": "Tonga", "LT": "Lithuania", "LU": "Luxembourg", "LR": "Liberia", "LS": "Lesotho", "TH": "Thailand", "TF": "French Southern Territories", "TG": "Togo", "TD": "Chad", "TC": "Turks and Caicos Islands", "LY": "Libya", "VA": "Vatican", "VC": "Saint Vincent and the Grenadines", "AE": "United Arab Emirates", "AD": "Andorra", "AG": "Antigua and Barbuda", "AF": "Afghanistan", "AI": "Anguilla", "VI": "U.S. Virgin Islands", "IS": "Iceland", "IR": "Iran", "AM": "Armenia", "AL": "Albania", "AO": "Angola", "AQ": "Antarctica", "AS": "American Samoa", "AR": "Argentina", "AU": "Australia", "AT": "Austria", "AW": "Aruba", "IN": "India", "AX": "Aland Islands", "AZ": "Azerbaijan", "IE": "Ireland", "ID": "Indonesia", "UA": "Ukraine", "QA": "Qatar", "MZ": "Mozambique"}
|
||||
253
app/Services/IPinfo/json/currency.json
Normal file
253
app/Services/IPinfo/json/currency.json
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
{
|
||||
"AD" : { "code": "EUR" ,"symbol": "€"},
|
||||
"AE" : { "code": "AED" ,"symbol": "د.إ"},
|
||||
"AF" : { "code": "AFN" ,"symbol": "؋"},
|
||||
"AG" : { "code": "XCD" ,"symbol": "$"},
|
||||
"AI" : { "code": "XCD" ,"symbol": "$"},
|
||||
"AL" : { "code": "ALL" ,"symbol": "L"},
|
||||
"AM" : { "code": "AMD" ,"symbol": "֏"},
|
||||
"AO" : { "code": "AOA" ,"symbol": "Kz"},
|
||||
"AQ" : { "code": "" ,"symbol": "$"},
|
||||
"AR" : { "code": "ARS" ,"symbol": "$"},
|
||||
"AS" : { "code": "USD" ,"symbol": "$"},
|
||||
"AT" : { "code": "EUR" ,"symbol": "€"},
|
||||
"AU" : { "code": "AUD" ,"symbol": "$"},
|
||||
"AW" : { "code": "AWG" ,"symbol": "ƒ"},
|
||||
"AX" : { "code": "EUR" ,"symbol": "€"},
|
||||
"AZ" : { "code": "AZN" ,"symbol": "₼"},
|
||||
"BA" : { "code": "BAM" ,"symbol": "KM"},
|
||||
"BB" : { "code": "BBD" ,"symbol": "$"},
|
||||
"BD" : { "code": "BDT" ,"symbol": "৳"},
|
||||
"BE" : { "code": "EUR" ,"symbol": "€"},
|
||||
"BF" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"BG" : { "code": "BGN" ,"symbol": "лв"},
|
||||
"BH" : { "code": "BHD" ,"symbol": ".د.ب"},
|
||||
"BI" : { "code": "BIF" ,"symbol": "FBu"},
|
||||
"BJ" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"BL" : { "code": "EUR" ,"symbol": "€"},
|
||||
"BM" : { "code": "BMD" ,"symbol": "$"},
|
||||
"BN" : { "code": "BND" ,"symbol": "$"},
|
||||
"BO" : { "code": "BOB" ,"symbol": "$b"},
|
||||
"BQ" : { "code": "USD" ,"symbol": "$"},
|
||||
"BR" : { "code": "BRL" ,"symbol": "R$"},
|
||||
"BS" : { "code": "BSD" ,"symbol": "$"},
|
||||
"BT" : { "code": "BTN" ,"symbol": "Nu."},
|
||||
"BV" : { "code": "NOK" ,"symbol": "kr"},
|
||||
"BW" : { "code": "BWP" ,"symbol": "P"},
|
||||
"BY" : { "code": "BYR" ,"symbol": "Br"},
|
||||
"BZ" : { "code": "BZD" ,"symbol": "BZ$"},
|
||||
"CA" : { "code": "CAD" ,"symbol": "$"},
|
||||
"CC" : { "code": "AUD" ,"symbol": "$"},
|
||||
"CD" : { "code": "CDF" ,"symbol": "FC"},
|
||||
"CF" : { "code": "XAF" ,"symbol": "FCFA"},
|
||||
"CG" : { "code": "XAF" ,"symbol": "FCFA"},
|
||||
"CH" : { "code": "CHF" ,"symbol": "CHF"},
|
||||
"CI" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"CK" : { "code": "NZD" ,"symbol": "$"},
|
||||
"CL" : { "code": "CLP" ,"symbol": "$"},
|
||||
"CM" : { "code": "XAF" ,"symbol": "FCFA"},
|
||||
"CN" : { "code": "CNY" ,"symbol": "¥"},
|
||||
"CO" : { "code": "COP" ,"symbol": "$"},
|
||||
"CR" : { "code": "CRC" ,"symbol": "₡"},
|
||||
"CU" : { "code": "CUP" ,"symbol": "₱"},
|
||||
"CV" : { "code": "CVE" ,"symbol": "$"},
|
||||
"CW" : { "code": "ANG" ,"symbol": "ƒ"},
|
||||
"CX" : { "code": "AUD" ,"symbol": "$"},
|
||||
"CY" : { "code": "EUR" ,"symbol": "€"},
|
||||
"CZ" : { "code": "CZK" ,"symbol": "Kč"},
|
||||
"DE" : { "code": "EUR" ,"symbol": "€"},
|
||||
"DJ" : { "code": "DJF" ,"symbol": "Fdj"},
|
||||
"DK" : { "code": "DKK" ,"symbol": "kr"},
|
||||
"DM" : { "code": "XCD" ,"symbol": "$"},
|
||||
"DO" : { "code": "DOP" ,"symbol": "RD$"},
|
||||
"DZ" : { "code": "DZD" ,"symbol": "دج"},
|
||||
"EC" : { "code": "USD" ,"symbol": "$"},
|
||||
"EE" : { "code": "EUR" ,"symbol": "€"},
|
||||
"EG" : { "code": "EGP" ,"symbol": "£"},
|
||||
"EH" : { "code": "MAD" ,"symbol": "MAD"},
|
||||
"ER" : { "code": "ERN" ,"symbol": "Nfk"},
|
||||
"ES" : { "code": "EUR" ,"symbol": "€"},
|
||||
"ET" : { "code": "ETB" ,"symbol": "Br"},
|
||||
"FI" : { "code": "EUR" ,"symbol": "€"},
|
||||
"FJ" : { "code": "FJD" ,"symbol": "$"},
|
||||
"FK" : { "code": "FKP" ,"symbol": "£"},
|
||||
"FM" : { "code": "USD" ,"symbol": "$"},
|
||||
"FO" : { "code": "DKK" ,"symbol": "kr"},
|
||||
"FR" : { "code": "EUR" ,"symbol": "€"},
|
||||
"GA" : { "code": "XAF" ,"symbol": "FCFA"},
|
||||
"GB" : { "code": "GBP" ,"symbol": "£"},
|
||||
"GD" : { "code": "XCD" ,"symbol": "$"},
|
||||
"GE" : { "code": "GEL" ,"symbol": "ლ"},
|
||||
"GF" : { "code": "EUR" ,"symbol": "€"},
|
||||
"GG" : { "code": "GBP" ,"symbol": "£"},
|
||||
"GH" : { "code": "GHS" ,"symbol": "GH₵"},
|
||||
"GI" : { "code": "GIP" ,"symbol": "£"},
|
||||
"GL" : { "code": "DKK" ,"symbol": "kr"},
|
||||
"GM" : { "code": "GMD" ,"symbol": "D"},
|
||||
"GN" : { "code": "GNF" ,"symbol": "FG"},
|
||||
"GP" : { "code": "EUR" ,"symbol": "€"},
|
||||
"GQ" : { "code": "XAF" ,"symbol": "FCFA"},
|
||||
"GR" : { "code": "EUR" ,"symbol": "€"},
|
||||
"GS" : { "code": "GBP" ,"symbol": "£"},
|
||||
"GT" : { "code": "GTQ" ,"symbol": "Q"},
|
||||
"GU" : { "code": "USD" ,"symbol": "$"},
|
||||
"GW" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"GY" : { "code": "GYD" ,"symbol": "$"},
|
||||
"HK" : { "code": "HKD" ,"symbol": "$"},
|
||||
"HM" : { "code": "AUD" ,"symbol": "$"},
|
||||
"HN" : { "code": "HNL" ,"symbol": "L"},
|
||||
"HR" : { "code": "HRK" ,"symbol": "kn"},
|
||||
"HT" : { "code": "HTG" ,"symbol": "G"},
|
||||
"HU" : { "code": "HUF" ,"symbol": "Ft"},
|
||||
"ID" : { "code": "IDR" ,"symbol": "Rp"},
|
||||
"IE" : { "code": "EUR" ,"symbol": "€"},
|
||||
"IL" : { "code": "ILS" ,"symbol": "₪"},
|
||||
"IM" : { "code": "GBP" ,"symbol": "£"},
|
||||
"IN" : { "code": "INR" ,"symbol": "₹"},
|
||||
"IO" : { "code": "USD" ,"symbol": "$"},
|
||||
"IQ" : { "code": "IQD" ,"symbol": "ع.د"},
|
||||
"IR" : { "code": "IRR" ,"symbol": "﷼"},
|
||||
"IS" : { "code": "ISK" ,"symbol": "kr"},
|
||||
"IT" : { "code": "EUR" ,"symbol": "€"},
|
||||
"JE" : { "code": "GBP" ,"symbol": "£"},
|
||||
"JM" : { "code": "JMD" ,"symbol": "J$"},
|
||||
"JO" : { "code": "JOD" ,"symbol": "JD"},
|
||||
"JP" : { "code": "JPY" ,"symbol": "¥"},
|
||||
"KE" : { "code": "KES" ,"symbol": "KSh"},
|
||||
"KG" : { "code": "KGS" ,"symbol": "лв"},
|
||||
"KH" : { "code": "KHR" ,"symbol": "៛"},
|
||||
"KI" : { "code": "AUD" ,"symbol": "$"},
|
||||
"KM" : { "code": "KMF" ,"symbol": "CF"},
|
||||
"KN" : { "code": "XCD" ,"symbol": "$"},
|
||||
"KP" : { "code": "KPW" ,"symbol": "₩"},
|
||||
"KR" : { "code": "KRW" ,"symbol": "₩"},
|
||||
"KW" : { "code": "KWD" ,"symbol": "KD"},
|
||||
"KY" : { "code": "KYD" ,"symbol": "$"},
|
||||
"KZ" : { "code": "KZT" ,"symbol": "₸"},
|
||||
"LA" : { "code": "LAK" ,"symbol": "₭"},
|
||||
"LB" : { "code": "LBP" ,"symbol": "£"},
|
||||
"LC" : { "code": "XCD" ,"symbol": "$"},
|
||||
"LI" : { "code": "CHF" ,"symbol": "CHF"},
|
||||
"LK" : { "code": "LKR" ,"symbol": "₨"},
|
||||
"LR" : { "code": "LRD" ,"symbol": "$"},
|
||||
"LS" : { "code": "LSL" ,"symbol": "M"},
|
||||
"LT" : { "code": "LTL" ,"symbol": "Lt"},
|
||||
"LU" : { "code": "EUR" ,"symbol": "€"},
|
||||
"LV" : { "code": "EUR" ,"symbol": "€"},
|
||||
"LY" : { "code": "LYD" ,"symbol": "LD"},
|
||||
"MA" : { "code": "MAD" ,"symbol": "MAD"},
|
||||
"MC" : { "code": "EUR" ,"symbol": "€"},
|
||||
"MD" : { "code": "MDL" ,"symbol": "lei"},
|
||||
"ME" : { "code": "EUR" ,"symbol": "€"},
|
||||
"MF" : { "code": "EUR" ,"symbol": "€"},
|
||||
"MG" : { "code": "MGA" ,"symbol": "Ar"},
|
||||
"MH" : { "code": "USD" ,"symbol": "$"},
|
||||
"MK" : { "code": "MKD" ,"symbol": "ден"},
|
||||
"ML" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"MM" : { "code": "MMK" ,"symbol": "K"},
|
||||
"MN" : { "code": "MNT" ,"symbol": "₮"},
|
||||
"MO" : { "code": "MOP" ,"symbol": "MOP$"},
|
||||
"MP" : { "code": "USD" ,"symbol": "$"},
|
||||
"MQ" : { "code": "EUR" ,"symbol": "€"},
|
||||
"MR" : { "code": "MRO" ,"symbol": "UM"},
|
||||
"MS" : { "code": "XCD" ,"symbol": "$"},
|
||||
"MT" : { "code": "EUR" ,"symbol": "€"},
|
||||
"MU" : { "code": "MUR" ,"symbol": "₨"},
|
||||
"MV" : { "code": "MVR" ,"symbol": "Rf"},
|
||||
"MW" : { "code": "MWK" ,"symbol": "MK"},
|
||||
"MX" : { "code": "MXN" ,"symbol": "$"},
|
||||
"MY" : { "code": "MYR" ,"symbol": "RM"},
|
||||
"MZ" : { "code": "MZN" ,"symbol": "MT"},
|
||||
"NA" : { "code": "NAD" ,"symbol": "$"},
|
||||
"NC" : { "code": "XPF" ,"symbol": "₣"},
|
||||
"NE" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"NF" : { "code": "AUD" ,"symbol": "$"},
|
||||
"NG" : { "code": "NGN" ,"symbol": "₦"},
|
||||
"NI" : { "code": "NIO" ,"symbol": "C$"},
|
||||
"NL" : { "code": "EUR" ,"symbol": "€"},
|
||||
"NO" : { "code": "NOK" ,"symbol": "kr"},
|
||||
"NP" : { "code": "NPR" ,"symbol": "₨"},
|
||||
"NR" : { "code": "AUD" ,"symbol": "$"},
|
||||
"NU" : { "code": "NZD" ,"symbol": "$"},
|
||||
"NZ" : { "code": "NZD" ,"symbol": "$"},
|
||||
"OM" : { "code": "OMR" ,"symbol": "﷼"},
|
||||
"PA" : { "code": "PAB" ,"symbol": "B/."},
|
||||
"PE" : { "code": "PEN" ,"symbol": "S/."},
|
||||
"PF" : { "code": "XPF" ,"symbol": "₣"},
|
||||
"PG" : { "code": "PGK" ,"symbol": "K"},
|
||||
"PH" : { "code": "PHP" ,"symbol": "₱"},
|
||||
"PK" : { "code": "PKR" ,"symbol": "₨"},
|
||||
"PL" : { "code": "PLN" ,"symbol": "zł"},
|
||||
"PM" : { "code": "EUR" ,"symbol": "€"},
|
||||
"PN" : { "code": "NZD" ,"symbol": "$"},
|
||||
"PR" : { "code": "USD" ,"symbol": "$"},
|
||||
"PS" : { "code": "ILS" ,"symbol": "₪"},
|
||||
"PT" : { "code": "EUR" ,"symbol": "€"},
|
||||
"PW" : { "code": "USD" ,"symbol": "$"},
|
||||
"PY" : { "code": "PYG" ,"symbol": "Gs"},
|
||||
"QA" : { "code": "QAR" ,"symbol": "﷼"},
|
||||
"RE" : { "code": "EUR" ,"symbol": "€"},
|
||||
"RO" : { "code": "RON" ,"symbol": "lei"},
|
||||
"RS" : { "code": "RSD" ,"symbol": "Дин."},
|
||||
"RU" : { "code": "RUB" ,"symbol": "₽"},
|
||||
"RW" : { "code": "RWF" ,"symbol": "R₣"},
|
||||
"SA" : { "code": "SAR" ,"symbol": "﷼"},
|
||||
"SB" : { "code": "SBD" ,"symbol": "$"},
|
||||
"SC" : { "code": "SCR" ,"symbol": "₨"},
|
||||
"SD" : { "code": "SDG" ,"symbol": "ج.س."},
|
||||
"SE" : { "code": "SEK" ,"symbol": "kr"},
|
||||
"SG" : { "code": "SGD" ,"symbol": "S$"},
|
||||
"SH" : { "code": "SHP" ,"symbol": "£"},
|
||||
"SI" : { "code": "EUR" ,"symbol": "€"},
|
||||
"SJ" : { "code": "NOK" ,"symbol": "kr"},
|
||||
"SK" : { "code": "EUR" ,"symbol": "€"},
|
||||
"SL" : { "code": "SLL" ,"symbol": "Le"},
|
||||
"SM" : { "code": "EUR" ,"symbol": "€"},
|
||||
"SN" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"SO" : { "code": "SOS" ,"symbol": "S"},
|
||||
"SR" : { "code": "SRD" ,"symbol": "$"},
|
||||
"SS" : { "code": "SSP" ,"symbol": "£"},
|
||||
"ST" : { "code": "STD" ,"symbol": "Db"},
|
||||
"SV" : { "code": "USD" ,"symbol": "$"},
|
||||
"SX" : { "code": "ANG" ,"symbol": "ƒ"},
|
||||
"SY" : { "code": "SYP" ,"symbol": "£"},
|
||||
"SZ" : { "code": "SZL" ,"symbol": "E"},
|
||||
"TC" : { "code": "USD" ,"symbol": "$"},
|
||||
"TD" : { "code": "XAF" ,"symbol": "FCFA"},
|
||||
"TF" : { "code": "EUR" ,"symbol": "€"},
|
||||
"TG" : { "code": "XOF" ,"symbol": "CFA"},
|
||||
"TH" : { "code": "THB" ,"symbol": "฿"},
|
||||
"TJ" : { "code": "TJS" ,"symbol": "SM"},
|
||||
"TK" : { "code": "NZD" ,"symbol": "$"},
|
||||
"TL" : { "code": "USD" ,"symbol": "$"},
|
||||
"TM" : { "code": "TMT" ,"symbol": "T"},
|
||||
"TN" : { "code": "TND" ,"symbol": "د.ت"},
|
||||
"TO" : { "code": "TOP" ,"symbol": "T$"},
|
||||
"TR" : { "code": "TRY" ,"symbol": "₺"},
|
||||
"TT" : { "code": "TTD" ,"symbol": "TT$"},
|
||||
"TV" : { "code": "AUD" ,"symbol": "$"},
|
||||
"TW" : { "code": "TWD" ,"symbol": "NT$"},
|
||||
"TZ" : { "code": "TZS" ,"symbol": "TSh"},
|
||||
"UA" : { "code": "UAH" ,"symbol": "₴"},
|
||||
"UG" : { "code": "UGX" ,"symbol": "USh"},
|
||||
"UM" : { "code": "USD" ,"symbol": "$"},
|
||||
"US" : { "code": "USD" ,"symbol": "$"},
|
||||
"UY" : { "code": "UYU" ,"symbol": "$U"},
|
||||
"UZ" : { "code": "UZS" ,"symbol": "лв"},
|
||||
"VA" : { "code": "EUR" ,"symbol": "€"},
|
||||
"VC" : { "code": "XCD" ,"symbol": "$"},
|
||||
"VE" : { "code": "VEF" ,"symbol": "Bs"},
|
||||
"VG" : { "code": "USD" ,"symbol": "$"},
|
||||
"VI" : { "code": "USD" ,"symbol": "$"},
|
||||
"VN" : { "code": "VND" ,"symbol": "₫"},
|
||||
"VU" : { "code": "VUV" ,"symbol": "VT"},
|
||||
"WF" : { "code": "XPF" ,"symbol": "₣"},
|
||||
"WS" : { "code": "WST" ,"symbol": "WS$"},
|
||||
"XK" : { "code": "EUR" ,"symbol": "€"},
|
||||
"YE" : { "code": "YER" ,"symbol": "﷼"},
|
||||
"YT" : { "code": "EUR" ,"symbol": "€"},
|
||||
"ZA" : { "code": "ZAR" ,"symbol": "R"},
|
||||
"ZM" : { "code": "ZMK" ,"symbol": "ZK"},
|
||||
"ZW" : { "code": "ZWL" ,"symbol": "$"}
|
||||
}
|
||||
|
||||
1
app/Services/IPinfo/json/eu.json
Normal file
1
app/Services/IPinfo/json/eu.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
["IE","AT","LT","LU","LV","DE","DK","SE","SI","SK","CZ","CY","NL","FI","FR","MT","ES","IT","EE","PL","PT","HU","HR","GR","RO","BG","BE"]
|
||||
252
app/Services/IPinfo/json/flags.json
Normal file
252
app/Services/IPinfo/json/flags.json
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
{
|
||||
"AD": {"emoji": "🇦🇩","unicode": "U+1F1E6 U+1F1E9"},
|
||||
"AE": {"emoji": "🇦🇪","unicode": "U+1F1E6 U+1F1EA"},
|
||||
"AF": {"emoji": "🇦🇫","unicode": "U+1F1E6 U+1F1EB"},
|
||||
"AG": {"emoji": "🇦🇬","unicode": "U+1F1E6 U+1F1EC"},
|
||||
"AI": {"emoji": "🇦🇮","unicode": "U+1F1E6 U+1F1EE"},
|
||||
"AL": {"emoji": "🇦🇱","unicode": "U+1F1E6 U+1F1F1"},
|
||||
"AM": {"emoji": "🇦🇲","unicode": "U+1F1E6 U+1F1F2"},
|
||||
"AO": {"emoji": "🇦🇴","unicode": "U+1F1E6 U+1F1F4"},
|
||||
"AQ": {"emoji": "🇦🇶","unicode": "U+1F1E6 U+1F1F6"},
|
||||
"AR": {"emoji": "🇦🇷","unicode": "U+1F1E6 U+1F1F7"},
|
||||
"AS": {"emoji": "🇦🇸","unicode": "U+1F1E6 U+1F1F8"},
|
||||
"AT": {"emoji": "🇦🇹","unicode": "U+1F1E6 U+1F1F9"},
|
||||
"AU": {"emoji": "🇦🇺","unicode": "U+1F1E6 U+1F1FA"},
|
||||
"AW": {"emoji": "🇦🇼","unicode": "U+1F1E6 U+1F1FC"},
|
||||
"AX": {"emoji": "🇦🇽","unicode": "U+1F1E6 U+1F1FD"},
|
||||
"AZ": {"emoji": "🇦🇿","unicode": "U+1F1E6 U+1F1FF"},
|
||||
"BA": {"emoji": "🇧🇦","unicode": "U+1F1E7 U+1F1E6"},
|
||||
"BB": {"emoji": "🇧🇧","unicode": "U+1F1E7 U+1F1E7"},
|
||||
"BD": {"emoji": "🇧🇩","unicode": "U+1F1E7 U+1F1E9"},
|
||||
"BE": {"emoji": "🇧🇪","unicode": "U+1F1E7 U+1F1EA"},
|
||||
"BF": {"emoji": "🇧🇫","unicode": "U+1F1E7 U+1F1EB"},
|
||||
"BG": {"emoji": "🇧🇬","unicode": "U+1F1E7 U+1F1EC"},
|
||||
"BH": {"emoji": "🇧🇭","unicode": "U+1F1E7 U+1F1ED"},
|
||||
"BI": {"emoji": "🇧🇮","unicode": "U+1F1E7 U+1F1EE"},
|
||||
"BJ": {"emoji": "🇧🇯","unicode": "U+1F1E7 U+1F1EF"},
|
||||
"BL": {"emoji": "🇧🇱","unicode": "U+1F1E7 U+1F1F1"},
|
||||
"BM": {"emoji": "🇧🇲","unicode": "U+1F1E7 U+1F1F2"},
|
||||
"BN": {"emoji": "🇧🇳","unicode": "U+1F1E7 U+1F1F3"},
|
||||
"BO": {"emoji": "🇧🇴","unicode": "U+1F1E7 U+1F1F4"},
|
||||
"BQ": {"emoji": "🇧🇶","unicode": "U+1F1E7 U+1F1F6"},
|
||||
"BR": {"emoji": "🇧🇷","unicode": "U+1F1E7 U+1F1F7"},
|
||||
"BS": {"emoji": "🇧🇸","unicode": "U+1F1E7 U+1F1F8"},
|
||||
"BT": {"emoji": "🇧🇹","unicode": "U+1F1E7 U+1F1F9"},
|
||||
"BV": {"emoji": "🇧🇻","unicode": "U+1F1E7 U+1F1FB"},
|
||||
"BW": {"emoji": "🇧🇼","unicode": "U+1F1E7 U+1F1FC"},
|
||||
"BY": {"emoji": "🇧🇾","unicode": "U+1F1E7 U+1F1FE"},
|
||||
"BZ": {"emoji": "🇧🇿","unicode": "U+1F1E7 U+1F1FF"},
|
||||
"CA": {"emoji": "🇨🇦","unicode": "U+1F1E8 U+1F1E6"},
|
||||
"CC": {"emoji": "🇨🇨","unicode": "U+1F1E8 U+1F1E8"},
|
||||
"CD": {"emoji": "🇨🇩","unicode": "U+1F1E8 U+1F1E9"},
|
||||
"CF": {"emoji": "🇨🇫","unicode": "U+1F1E8 U+1F1EB"},
|
||||
"CG": {"emoji": "🇨🇬","unicode": "U+1F1E8 U+1F1EC"},
|
||||
"CH": {"emoji": "🇨🇭","unicode": "U+1F1E8 U+1F1ED"},
|
||||
"CI": {"emoji": "🇨🇮","unicode": "U+1F1E8 U+1F1EE"},
|
||||
"CK": {"emoji": "🇨🇰","unicode": "U+1F1E8 U+1F1F0"},
|
||||
"CL": {"emoji": "🇨🇱","unicode": "U+1F1E8 U+1F1F1"},
|
||||
"CM": {"emoji": "🇨🇲","unicode": "U+1F1E8 U+1F1F2"},
|
||||
"CN": {"emoji": "🇨🇳","unicode": "U+1F1E8 U+1F1F3"},
|
||||
"CO": {"emoji": "🇨🇴","unicode": "U+1F1E8 U+1F1F4"},
|
||||
"CR": {"emoji": "🇨🇷","unicode": "U+1F1E8 U+1F1F7"},
|
||||
"CU": {"emoji": "🇨🇺","unicode": "U+1F1E8 U+1F1FA"},
|
||||
"CV": {"emoji": "🇨🇻","unicode": "U+1F1E8 U+1F1FB"},
|
||||
"CW": {"emoji": "🇨🇼","unicode": "U+1F1E8 U+1F1FC"},
|
||||
"CX": {"emoji": "🇨🇽","unicode": "U+1F1E8 U+1F1FD"},
|
||||
"CY": {"emoji": "🇨🇾","unicode": "U+1F1E8 U+1F1FE"},
|
||||
"CZ": {"emoji": "🇨🇿","unicode": "U+1F1E8 U+1F1FF"},
|
||||
"DE": {"emoji": "🇩🇪","unicode": "U+1F1E9 U+1F1EA"},
|
||||
"DJ": {"emoji": "🇩🇯","unicode": "U+1F1E9 U+1F1EF"},
|
||||
"DK": {"emoji": "🇩🇰","unicode": "U+1F1E9 U+1F1F0"},
|
||||
"DM": {"emoji": "🇩🇲","unicode": "U+1F1E9 U+1F1F2"},
|
||||
"DO": {"emoji": "🇩🇴","unicode": "U+1F1E9 U+1F1F4"},
|
||||
"DZ": {"emoji": "🇩🇿","unicode": "U+1F1E9 U+1F1FF"},
|
||||
"EC": {"emoji": "🇪🇨","unicode": "U+1F1EA U+1F1E8"},
|
||||
"EE": {"emoji": "🇪🇪","unicode": "U+1F1EA U+1F1EA"},
|
||||
"EG": {"emoji": "🇪🇬","unicode": "U+1F1EA U+1F1EC"},
|
||||
"EH": {"emoji": "🇪🇭","unicode": "U+1F1EA U+1F1ED"},
|
||||
"ER": {"emoji": "🇪🇷","unicode": "U+1F1EA U+1F1F7"},
|
||||
"ES": {"emoji": "🇪🇸","unicode": "U+1F1EA U+1F1F8"},
|
||||
"ET": {"emoji": "🇪🇹","unicode": "U+1F1EA U+1F1F9"},
|
||||
"FI": {"emoji": "🇫🇮","unicode": "U+1F1EB U+1F1EE"},
|
||||
"FJ": {"emoji": "🇫🇯","unicode": "U+1F1EB U+1F1EF"},
|
||||
"FK": {"emoji": "🇫🇰","unicode": "U+1F1EB U+1F1F0"},
|
||||
"FM": {"emoji": "🇫🇲","unicode": "U+1F1EB U+1F1F2"},
|
||||
"FO": {"emoji": "🇫🇴","unicode": "U+1F1EB U+1F1F4"},
|
||||
"FR": {"emoji": "🇫🇷","unicode": "U+1F1EB U+1F1F7"},
|
||||
"GA": {"emoji": "🇬🇦","unicode": "U+1F1EC U+1F1E6"},
|
||||
"GB": {"emoji": "🇬🇧","unicode": "U+1F1EC U+1F1E7"},
|
||||
"GD": {"emoji": "🇬🇩","unicode": "U+1F1EC U+1F1E9"},
|
||||
"GE": {"emoji": "🇬🇪","unicode": "U+1F1EC U+1F1EA"},
|
||||
"GF": {"emoji": "🇬🇫","unicode": "U+1F1EC U+1F1EB"},
|
||||
"GG": {"emoji": "🇬🇬","unicode": "U+1F1EC U+1F1EC"},
|
||||
"GH": {"emoji": "🇬🇭","unicode": "U+1F1EC U+1F1ED"},
|
||||
"GI": {"emoji": "🇬🇮","unicode": "U+1F1EC U+1F1EE"},
|
||||
"GL": {"emoji": "🇬🇱","unicode": "U+1F1EC U+1F1F1"},
|
||||
"GM": {"emoji": "🇬🇲","unicode": "U+1F1EC U+1F1F2"},
|
||||
"GN": {"emoji": "🇬🇳","unicode": "U+1F1EC U+1F1F3"},
|
||||
"GP": {"emoji": "🇬🇵","unicode": "U+1F1EC U+1F1F5"},
|
||||
"GQ": {"emoji": "🇬🇶","unicode": "U+1F1EC U+1F1F6"},
|
||||
"GR": {"emoji": "🇬🇷","unicode": "U+1F1EC U+1F1F7"},
|
||||
"GS": {"emoji": "🇬🇸","unicode": "U+1F1EC U+1F1F8"},
|
||||
"GT": {"emoji": "🇬🇹","unicode": "U+1F1EC U+1F1F9"},
|
||||
"GU": {"emoji": "🇬🇺","unicode": "U+1F1EC U+1F1FA"},
|
||||
"GW": {"emoji": "🇬🇼","unicode": "U+1F1EC U+1F1FC"},
|
||||
"GY": {"emoji": "🇬🇾","unicode": "U+1F1EC U+1F1FE"},
|
||||
"HK": {"emoji": "🇭🇰","unicode": "U+1F1ED U+1F1F0"},
|
||||
"HM": {"emoji": "🇭🇲","unicode": "U+1F1ED U+1F1F2"},
|
||||
"HN": {"emoji": "🇭🇳","unicode": "U+1F1ED U+1F1F3"},
|
||||
"HR": {"emoji": "🇭🇷","unicode": "U+1F1ED U+1F1F7"},
|
||||
"HT": {"emoji": "🇭🇹","unicode": "U+1F1ED U+1F1F9"},
|
||||
"HU": {"emoji": "🇭🇺","unicode": "U+1F1ED U+1F1FA"},
|
||||
"ID": {"emoji": "🇮🇩","unicode": "U+1F1EE U+1F1E9"},
|
||||
"IE": {"emoji": "🇮🇪","unicode": "U+1F1EE U+1F1EA"},
|
||||
"IL": {"emoji": "🇮🇱","unicode": "U+1F1EE U+1F1F1"},
|
||||
"IM": {"emoji": "🇮🇲","unicode": "U+1F1EE U+1F1F2"},
|
||||
"IN": {"emoji": "🇮🇳","unicode": "U+1F1EE U+1F1F3"},
|
||||
"IO": {"emoji": "🇮🇴","unicode": "U+1F1EE U+1F1F4"},
|
||||
"IQ": {"emoji": "🇮🇶","unicode": "U+1F1EE U+1F1F6"},
|
||||
"IR": {"emoji": "🇮🇷","unicode": "U+1F1EE U+1F1F7"},
|
||||
"IS": {"emoji": "🇮🇸","unicode": "U+1F1EE U+1F1F8"},
|
||||
"IT": {"emoji": "🇮🇹","unicode": "U+1F1EE U+1F1F9"},
|
||||
"JE": {"emoji": "🇯🇪","unicode": "U+1F1EF U+1F1EA"},
|
||||
"JM": {"emoji": "🇯🇲","unicode": "U+1F1EF U+1F1F2"},
|
||||
"JO": {"emoji": "🇯🇴","unicode": "U+1F1EF U+1F1F4"},
|
||||
"JP": {"emoji": "🇯🇵","unicode": "U+1F1EF U+1F1F5"},
|
||||
"KE": {"emoji": "🇰🇪","unicode": "U+1F1F0 U+1F1EA"},
|
||||
"KG": {"emoji": "🇰🇬","unicode": "U+1F1F0 U+1F1EC"},
|
||||
"KH": {"emoji": "🇰🇭","unicode": "U+1F1F0 U+1F1ED"},
|
||||
"KI": {"emoji": "🇰🇮","unicode": "U+1F1F0 U+1F1EE"},
|
||||
"KM": {"emoji": "🇰🇲","unicode": "U+1F1F0 U+1F1F2"},
|
||||
"KN": {"emoji": "🇰🇳","unicode": "U+1F1F0 U+1F1F3"},
|
||||
"KP": {"emoji": "🇰🇵","unicode": "U+1F1F0 U+1F1F5"},
|
||||
"KR": {"emoji": "🇰🇷","unicode": "U+1F1F0 U+1F1F7"},
|
||||
"KW": {"emoji": "🇰🇼","unicode": "U+1F1F0 U+1F1FC"},
|
||||
"KY": {"emoji": "🇰🇾","unicode": "U+1F1F0 U+1F1FE"},
|
||||
"KZ": {"emoji": "🇰🇿","unicode": "U+1F1F0 U+1F1FF"},
|
||||
"LA": {"emoji": "🇱🇦","unicode": "U+1F1F1 U+1F1E6"},
|
||||
"LB": {"emoji": "🇱🇧","unicode": "U+1F1F1 U+1F1E7"},
|
||||
"LC": {"emoji": "🇱🇨","unicode": "U+1F1F1 U+1F1E8"},
|
||||
"LI": {"emoji": "🇱🇮","unicode": "U+1F1F1 U+1F1EE"},
|
||||
"LK": {"emoji": "🇱🇰","unicode": "U+1F1F1 U+1F1F0"},
|
||||
"LR": {"emoji": "🇱🇷","unicode": "U+1F1F1 U+1F1F7"},
|
||||
"LS": {"emoji": "🇱🇸","unicode": "U+1F1F1 U+1F1F8"},
|
||||
"LT": {"emoji": "🇱🇹","unicode": "U+1F1F1 U+1F1F9"},
|
||||
"LU": {"emoji": "🇱🇺","unicode": "U+1F1F1 U+1F1FA"},
|
||||
"LV": {"emoji": "🇱🇻","unicode": "U+1F1F1 U+1F1FB"},
|
||||
"LY": {"emoji": "🇱🇾","unicode": "U+1F1F1 U+1F1FE"},
|
||||
"MA": {"emoji": "🇲🇦","unicode": "U+1F1F2 U+1F1E6"},
|
||||
"MC": {"emoji": "🇲🇨","unicode": "U+1F1F2 U+1F1E8"},
|
||||
"MD": {"emoji": "🇲🇩","unicode": "U+1F1F2 U+1F1E9"},
|
||||
"ME": {"emoji": "🇲🇪","unicode": "U+1F1F2 U+1F1EA"},
|
||||
"MF": {"emoji": "🇲🇫","unicode": "U+1F1F2 U+1F1EB"},
|
||||
"MG": {"emoji": "🇲🇬","unicode": "U+1F1F2 U+1F1EC"},
|
||||
"MH": {"emoji": "🇲🇭","unicode": "U+1F1F2 U+1F1ED"},
|
||||
"MK": {"emoji": "🇲🇰","unicode": "U+1F1F2 U+1F1F0"},
|
||||
"ML": {"emoji": "🇲🇱","unicode": "U+1F1F2 U+1F1F1"},
|
||||
"MM": {"emoji": "🇲🇲","unicode": "U+1F1F2 U+1F1F2"},
|
||||
"MN": {"emoji": "🇲🇳","unicode": "U+1F1F2 U+1F1F3"},
|
||||
"MO": {"emoji": "🇲🇴","unicode": "U+1F1F2 U+1F1F4"},
|
||||
"MP": {"emoji": "🇲🇵","unicode": "U+1F1F2 U+1F1F5"},
|
||||
"MQ": {"emoji": "🇲🇶","unicode": "U+1F1F2 U+1F1F6"},
|
||||
"MR": {"emoji": "🇲🇷","unicode": "U+1F1F2 U+1F1F7"},
|
||||
"MS": {"emoji": "🇲🇸","unicode": "U+1F1F2 U+1F1F8"},
|
||||
"MT": {"emoji": "🇲🇹","unicode": "U+1F1F2 U+1F1F9"},
|
||||
"MU": {"emoji": "🇲🇺","unicode": "U+1F1F2 U+1F1FA"},
|
||||
"MV": {"emoji": "🇲🇻","unicode": "U+1F1F2 U+1F1FB"},
|
||||
"MW": {"emoji": "🇲🇼","unicode": "U+1F1F2 U+1F1FC"},
|
||||
"MX": {"emoji": "🇲🇽","unicode": "U+1F1F2 U+1F1FD"},
|
||||
"MY": {"emoji": "🇲🇾","unicode": "U+1F1F2 U+1F1FE"},
|
||||
"MZ": {"emoji": "🇲🇿","unicode": "U+1F1F2 U+1F1FF"},
|
||||
"NA": {"emoji": "🇳🇦","unicode": "U+1F1F3 U+1F1E6"},
|
||||
"NC": {"emoji": "🇳🇨","unicode": "U+1F1F3 U+1F1E8"},
|
||||
"NE": {"emoji": "🇳🇪","unicode": "U+1F1F3 U+1F1EA"},
|
||||
"NF": {"emoji": "🇳🇫","unicode": "U+1F1F3 U+1F1EB"},
|
||||
"NG": {"emoji": "🇳🇬","unicode": "U+1F1F3 U+1F1EC"},
|
||||
"NI": {"emoji": "🇳🇮","unicode": "U+1F1F3 U+1F1EE"},
|
||||
"NL": {"emoji": "🇳🇱","unicode": "U+1F1F3 U+1F1F1"},
|
||||
"NO": {"emoji": "🇳🇴","unicode": "U+1F1F3 U+1F1F4"},
|
||||
"NP": {"emoji": "🇳🇵","unicode": "U+1F1F3 U+1F1F5"},
|
||||
"NR": {"emoji": "🇳🇷","unicode": "U+1F1F3 U+1F1F7"},
|
||||
"NU": {"emoji": "🇳🇺","unicode": "U+1F1F3 U+1F1FA"},
|
||||
"NZ": {"emoji": "🇳🇿","unicode": "U+1F1F3 U+1F1FF"},
|
||||
"OM": {"emoji": "🇴🇲","unicode": "U+1F1F4 U+1F1F2"},
|
||||
"PA": {"emoji": "🇵🇦","unicode": "U+1F1F5 U+1F1E6"},
|
||||
"PE": {"emoji": "🇵🇪","unicode": "U+1F1F5 U+1F1EA"},
|
||||
"PF": {"emoji": "🇵🇫","unicode": "U+1F1F5 U+1F1EB"},
|
||||
"PG": {"emoji": "🇵🇬","unicode": "U+1F1F5 U+1F1EC"},
|
||||
"PH": {"emoji": "🇵🇭","unicode": "U+1F1F5 U+1F1ED"},
|
||||
"PK": {"emoji": "🇵🇰","unicode": "U+1F1F5 U+1F1F0"},
|
||||
"PL": {"emoji": "🇵🇱","unicode": "U+1F1F5 U+1F1F1"},
|
||||
"PM": {"emoji": "🇵🇲","unicode": "U+1F1F5 U+1F1F2"},
|
||||
"PN": {"emoji": "🇵🇳","unicode": "U+1F1F5 U+1F1F3"},
|
||||
"PR": {"emoji": "🇵🇷","unicode": "U+1F1F5 U+1F1F7"},
|
||||
"PS": {"emoji": "🇵🇸","unicode": "U+1F1F5 U+1F1F8"},
|
||||
"PT": {"emoji": "🇵🇹","unicode": "U+1F1F5 U+1F1F9"},
|
||||
"PW": {"emoji": "🇵🇼","unicode": "U+1F1F5 U+1F1FC"},
|
||||
"PY": {"emoji": "🇵🇾","unicode": "U+1F1F5 U+1F1FE"},
|
||||
"QA": {"emoji": "🇶🇦","unicode": "U+1F1F6 U+1F1E6"},
|
||||
"RE": {"emoji": "🇷🇪","unicode": "U+1F1F7 U+1F1EA"},
|
||||
"RO": {"emoji": "🇷🇴","unicode": "U+1F1F7 U+1F1F4"},
|
||||
"RS": {"emoji": "🇷🇸","unicode": "U+1F1F7 U+1F1F8"},
|
||||
"RU": {"emoji": "🇷🇺","unicode": "U+1F1F7 U+1F1FA"},
|
||||
"RW": {"emoji": "🇷🇼","unicode": "U+1F1F7 U+1F1FC"},
|
||||
"SA": {"emoji": "🇸🇦","unicode": "U+1F1F8 U+1F1E6"},
|
||||
"SB": {"emoji": "🇸🇧","unicode": "U+1F1F8 U+1F1E7"},
|
||||
"SC": {"emoji": "🇸🇨","unicode": "U+1F1F8 U+1F1E8"},
|
||||
"SD": {"emoji": "🇸🇩","unicode": "U+1F1F8 U+1F1E9"},
|
||||
"SE": {"emoji": "🇸🇪","unicode": "U+1F1F8 U+1F1EA"},
|
||||
"SG": {"emoji": "🇸🇬","unicode": "U+1F1F8 U+1F1EC"},
|
||||
"SH": {"emoji": "🇸🇭","unicode": "U+1F1F8 U+1F1ED"},
|
||||
"SI": {"emoji": "🇸🇮","unicode": "U+1F1F8 U+1F1EE"},
|
||||
"SJ": {"emoji": "🇸🇯","unicode": "U+1F1F8 U+1F1EF"},
|
||||
"SK": {"emoji": "🇸🇰","unicode": "U+1F1F8 U+1F1F0"},
|
||||
"SL": {"emoji": "🇸🇱","unicode": "U+1F1F8 U+1F1F1"},
|
||||
"SM": {"emoji": "🇸🇲","unicode": "U+1F1F8 U+1F1F2"},
|
||||
"SN": {"emoji": "🇸🇳","unicode": "U+1F1F8 U+1F1F3"},
|
||||
"SO": {"emoji": "🇸🇴","unicode": "U+1F1F8 U+1F1F4"},
|
||||
"SR": {"emoji": "🇸🇷","unicode": "U+1F1F8 U+1F1F7"},
|
||||
"SS": {"emoji": "🇸🇸","unicode": "U+1F1F8 U+1F1F8"},
|
||||
"ST": {"emoji": "🇸🇹","unicode": "U+1F1F8 U+1F1F9"},
|
||||
"SV": {"emoji": "🇸🇻","unicode": "U+1F1F8 U+1F1FB"},
|
||||
"SX": {"emoji": "🇸🇽","unicode": "U+1F1F8 U+1F1FD"},
|
||||
"SY": {"emoji": "🇸🇾","unicode": "U+1F1F8 U+1F1FE"},
|
||||
"SZ": {"emoji": "🇸🇿","unicode": "U+1F1F8 U+1F1FF"},
|
||||
"TC": {"emoji": "🇹🇨","unicode": "U+1F1F9 U+1F1E8"},
|
||||
"TD": {"emoji": "🇹🇩","unicode": "U+1F1F9 U+1F1E9"},
|
||||
"TF": {"emoji": "🇹🇫","unicode": "U+1F1F9 U+1F1EB"},
|
||||
"TG": {"emoji": "🇹🇬","unicode": "U+1F1F9 U+1F1EC"},
|
||||
"TH": {"emoji": "🇹🇭","unicode": "U+1F1F9 U+1F1ED"},
|
||||
"TJ": {"emoji": "🇹🇯","unicode": "U+1F1F9 U+1F1EF"},
|
||||
"TK": {"emoji": "🇹🇰","unicode": "U+1F1F9 U+1F1F0"},
|
||||
"TL": {"emoji": "🇹🇱","unicode": "U+1F1F9 U+1F1F1"},
|
||||
"TM": {"emoji": "🇹🇲","unicode": "U+1F1F9 U+1F1F2"},
|
||||
"TN": {"emoji": "🇹🇳","unicode": "U+1F1F9 U+1F1F3"},
|
||||
"TO": {"emoji": "🇹🇴","unicode": "U+1F1F9 U+1F1F4"},
|
||||
"TR": {"emoji": "🇹🇷","unicode": "U+1F1F9 U+1F1F7"},
|
||||
"TT": {"emoji": "🇹🇹","unicode": "U+1F1F9 U+1F1F9"},
|
||||
"TV": {"emoji": "🇹🇻","unicode": "U+1F1F9 U+1F1FB"},
|
||||
"TW": {"emoji": "🇹🇼","unicode": "U+1F1F9 U+1F1FC"},
|
||||
"TZ": {"emoji": "🇹🇿","unicode": "U+1F1F9 U+1F1FF"},
|
||||
"UA": {"emoji": "🇺🇦","unicode": "U+1F1FA U+1F1E6"},
|
||||
"UG": {"emoji": "🇺🇬","unicode": "U+1F1FA U+1F1EC"},
|
||||
"UM": {"emoji": "🇺🇲","unicode": "U+1F1FA U+1F1F2"},
|
||||
"US": {"emoji": "🇺🇸","unicode": "U+1F1FA U+1F1F8"},
|
||||
"UY": {"emoji": "🇺🇾","unicode": "U+1F1FA U+1F1FE"},
|
||||
"UZ": {"emoji": "🇺🇿","unicode": "U+1F1FA U+1F1FF"},
|
||||
"VA": {"emoji": "🇻🇦","unicode": "U+1F1FB U+1F1E6"},
|
||||
"VC": {"emoji": "🇻🇨","unicode": "U+1F1FB U+1F1E8"},
|
||||
"VE": {"emoji": "🇻🇪","unicode": "U+1F1FB U+1F1EA"},
|
||||
"VG": {"emoji": "🇻🇬","unicode": "U+1F1FB U+1F1EC"},
|
||||
"VI": {"emoji": "🇻🇮","unicode": "U+1F1FB U+1F1EE"},
|
||||
"VN": {"emoji": "🇻🇳","unicode": "U+1F1FB U+1F1F3"},
|
||||
"VU": {"emoji": "🇻🇺","unicode": "U+1F1FB U+1F1FA"},
|
||||
"WF": {"emoji": "🇼🇫","unicode": "U+1F1FC U+1F1EB"},
|
||||
"WS": {"emoji": "🇼🇸","unicode": "U+1F1FC U+1F1F8"},
|
||||
"XK": {"emoji": "🇽🇰","unicode": "U+1F1FD U+1F1F0"},
|
||||
"YE": {"emoji": "🇾🇪","unicode": "U+1F1FE U+1F1EA"},
|
||||
"YT": {"emoji": "🇾🇹","unicode": "U+1F1FE U+1F1F9"},
|
||||
"ZA": {"emoji": "🇿🇦","unicode": "U+1F1FF U+1F1E6"},
|
||||
"ZM": {"emoji": "🇿🇲","unicode": "U+1F1FF U+1F1F2"},
|
||||
"ZW": {"emoji": "🇿🇼","unicode": "U+1F1FF U+1F1FC"}
|
||||
}
|
||||
|
|
@ -61,6 +61,7 @@ class Invoice
|
|||
}else{
|
||||
$bcc[] = config('app.checkout_mail');
|
||||
}
|
||||
Mail::to($billing_email)->bcc($bcc)->send(new MailInvoice($shopping_order, $user_invoice));
|
||||
|
||||
Mail::to($billing_email)->bcc($bcc)->locale($shopping_order->getLocale())->send(new MailInvoice($shopping_order, $user_invoice));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
34
app/Services/MyLog.php
Normal file
34
app/Services/MyLog.php
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Mail\MailLog;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
|
||||
class MyLog
|
||||
{
|
||||
|
||||
|
||||
|
||||
public static function writeLog($channel = 'payment', $context = 'error', $message = '', $data = []){
|
||||
|
||||
switch ($context) {
|
||||
case 'notice':
|
||||
\Log::channel($channel)->notice($message.' : '.json_encode($data));
|
||||
break;
|
||||
case 'warning':
|
||||
\Log::channel($channel)->warning($message.' : '.json_encode($data));
|
||||
break;
|
||||
case 'info':
|
||||
\Log::channel($channel)->info($message.' : '.json_encode($data));
|
||||
break;
|
||||
default:
|
||||
\Log::channel($channel)->error($message.' : '.json_encode($data));
|
||||
break;
|
||||
}
|
||||
Mail::to(config('app.exception_mail'))->send(new MailLog($channel, $context, $message, $data));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -5,6 +5,7 @@ namespace App\Services;
|
|||
use App\User;
|
||||
use App\Models\UserLevel;
|
||||
use App\Mail\MailCheckout;
|
||||
use App\Services\UserUtil;
|
||||
use App\Models\ProductBuying;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\UserCreditItem;
|
||||
|
|
@ -18,52 +19,52 @@ class Payment
|
|||
{
|
||||
|
||||
public static $txaction_text = [
|
||||
'paid' => "bezahlt",
|
||||
'appointed' => "offen",
|
||||
'failed' => "abbruch",
|
||||
'extern' => "offen", //offen
|
||||
'extern_paid' => "bezahlt",
|
||||
'invoice_open' => "offen",
|
||||
'invoice_paid' => "bezahlt",
|
||||
'invoice_non' => "keine Zahlung",
|
||||
'NULL' => 'keine Zahlung',
|
||||
'paid' => 'paid',
|
||||
'appointed' => 'open',
|
||||
'failed' => 'failed',
|
||||
'extern' => 'open', //offen
|
||||
'extern_paid' => 'paid',
|
||||
'invoice_open' => 'open',
|
||||
'invoice_paid' => 'paid',
|
||||
'invoice_non' => 'no_payment',
|
||||
'NULL' => 'no_payment',
|
||||
];
|
||||
|
||||
public static $txaction_filter_text = [
|
||||
'paid' => "Zahlung bezahlt",
|
||||
'appointed' => "Zahlung offen",
|
||||
'failed' => "Zahlung abbruch",
|
||||
'extern' => "Extern offen", //offen
|
||||
'extern_paid' => "Extern bezahlt",
|
||||
'invoice_open' => "Rechnung offen",
|
||||
'invoice_paid' => "Rechnung bezahlt",
|
||||
'invoice_non' => "Rechnung keine Zahlung",
|
||||
'NULL' => 'keine Zahlung',
|
||||
'paid' => 'paymend_paid',
|
||||
'appointed' => 'paymend_open',
|
||||
'failed' => 'paymend_failed',
|
||||
'extern' => 'extern_open', //offen
|
||||
'extern_paid' => 'extern_paid',
|
||||
'invoice_open' => 'invoice_open',
|
||||
'invoice_paid' => 'invoice_paid',
|
||||
'invoice_non' => 'invoice_no_payment',
|
||||
'NULL' => 'no_payment',
|
||||
];
|
||||
|
||||
public static $txaction_invoice = [
|
||||
'invoice_open' => "Rechnung offen",
|
||||
'invoice_paid' => "Rechnung bezahlt",
|
||||
'invoice_non' => 'keine Zahlung',
|
||||
'invoice_open' => 'invoice_open',
|
||||
'invoice_paid' => 'invoice_paid',
|
||||
'invoice_non' => 'no_payment',
|
||||
];
|
||||
|
||||
public static $txaction_color = [
|
||||
'paid' => "success",
|
||||
'appointed' => "warning",
|
||||
'failed' => "danger",
|
||||
'extern' => "warning",
|
||||
'extern_paid' => "success",
|
||||
'invoice_open' => "warning",
|
||||
'invoice_paid' => "success",
|
||||
'invoice_non' => "failed",
|
||||
'paid' => 'success',
|
||||
'appointed' => 'warning',
|
||||
'failed' => 'danger',
|
||||
'extern' => 'warning',
|
||||
'extern_paid' => 'success',
|
||||
'invoice_open' => 'warning',
|
||||
'invoice_paid' => 'success',
|
||||
'invoice_non' => 'failed',
|
||||
];
|
||||
|
||||
|
||||
public static function getFormattedTxaction($txaction){
|
||||
if($txaction && isset(self::$txaction_text[$txaction])){
|
||||
return self::$txaction_text[$txaction];
|
||||
return __('payment.'.self::$txaction_text[$txaction]);
|
||||
}
|
||||
return self::$txaction_text['NULL'];
|
||||
return __('payment.'.self::$txaction_text['NULL']);
|
||||
}
|
||||
|
||||
public static function getFormattedTxactionColor($txaction){
|
||||
|
|
@ -73,6 +74,22 @@ class Payment
|
|||
return "warning";
|
||||
}
|
||||
|
||||
public static function getTransTxactionFilterText(){
|
||||
$ret = [];
|
||||
foreach(self::$txaction_filter_text as $key=>$val){
|
||||
$ret[$key] = trans('payment.'.$val);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getTransTxactionInvoice(){
|
||||
$ret = [];
|
||||
foreach(self::$txaction_invoice as $key=>$val){
|
||||
$ret[$key] = trans('payment.'.$val);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function getShoppingOrderBadge(ShoppingOrder $shopping_order){
|
||||
if($shopping_order->mode === 'test'){
|
||||
return '<span class="badge badge-pill badge-default">'.strtoupper($shopping_order->mode).' - '.self::getFormattedTxaction($shopping_order->txaction).'</span>';
|
||||
|
|
@ -95,6 +112,8 @@ class Payment
|
|||
'user_id' => $user->id,
|
||||
'credit' => $credit,
|
||||
'message' => $message,
|
||||
'from_month' => date('n'),
|
||||
'from_year' => date('Y'),
|
||||
'status' => $status,
|
||||
]);
|
||||
}
|
||||
|
|
@ -171,6 +190,14 @@ class Payment
|
|||
$user->payment_order_id = $shopping_order_item->product->id; //34
|
||||
$user->payment_account = $date;
|
||||
$user->wizard = 100;
|
||||
//only date is > now and acount is deactive.
|
||||
if($date > \Carbon::now()){
|
||||
if($user->active === 0){
|
||||
$user->active = true;
|
||||
UserUtil::reactiveUserResetChilds($user->id, 'on payment_for_account Payment');
|
||||
}
|
||||
}
|
||||
|
||||
$shopping_order->setUserHistoryValue(['status' => 9]);
|
||||
}
|
||||
if($shopping_order_item->product->getActionName($do) === 'payment_for_shop'){
|
||||
|
|
@ -210,7 +237,6 @@ class Payment
|
|||
}
|
||||
|
||||
//make Invoice and
|
||||
|
||||
$invoice_repo = new InvoiceRepository($shopping_order);
|
||||
if(!$shopping_order->isInvoice()){
|
||||
$invoice_repo->createAndSalesVolume();
|
||||
|
|
@ -237,6 +263,6 @@ class Payment
|
|||
if(!$shopping_order->shopping_user->is_like && $shopping_order->shopping_user->member){
|
||||
$bcc[] = $shopping_order->shopping_user->member->email;
|
||||
}
|
||||
Mail::to($billing_email)->bcc($bcc)->send(new MailCheckout($data['txaction'], $shopping_order, $shopping_payment, $data['send_link'], $data['mode']));
|
||||
Mail::to($billing_email)->bcc($bcc)->locale($shopping_order->getLocale())->send(new MailCheckout($data['txaction'], $shopping_order, $shopping_payment, $data['send_link'], $data['mode']));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ class PaymentHelper
|
|||
$shopping_user = new ShoppingUser();
|
||||
$shopping_user->auth_user_id = $user->id;
|
||||
$shopping_user->mode = 'prev';
|
||||
$shopping_user->language = $user->getLocale();
|
||||
$shopping_user->billing_salutation = $user->account->salutation;
|
||||
$shopping_user->billing_company = $user->account->company;
|
||||
$shopping_user->billing_firstname = $user->account->first_name;
|
||||
|
|
@ -121,6 +122,7 @@ class PaymentHelper
|
|||
'shopping_user_id' => $shopping_user->id,
|
||||
'auth_user_id' => $shopping_user->auth_user_id,
|
||||
'country_id' => Yard::instance('shopping')->getShippingCountryId(),
|
||||
'language' => \App::getLocale(),
|
||||
'user_shop_id' => 1,
|
||||
'payment_for' => $shopping_user->getOrderPaymentFor(),
|
||||
'total' => Yard::instance('shopping')->total(2, '.', ''),
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace App\Services;
|
|||
|
||||
//require 'vendor/autoload.php';
|
||||
use Exception;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
|
|
@ -41,7 +42,7 @@ class Payone {
|
|||
* The URL of the Payone API
|
||||
*/
|
||||
const PAYONE_SERVER_API_URL = 'https://api.pay1.de/post-gateway/';
|
||||
const PAYONE_CLIENT_API_URL = 'https://secure.pay1.de/client-api//';
|
||||
const PAYONE_CLIENT_API_URL = 'https://secure.pay1.de/client-api/';
|
||||
|
||||
/**
|
||||
* performing the HTTP POST request to the PAYONE platform
|
||||
|
|
@ -57,35 +58,84 @@ class Payone {
|
|||
if ($responsetype === "json") {
|
||||
// appends the accept: application/json header to the request
|
||||
// This is used to retrieve structured JSON in the response
|
||||
$client = new Client(['headers' => ['accept' => 'application/json']]);
|
||||
// $client = new Client(['headers' => ['accept' => 'application/json', 'content-type' => 'text/plain;charset=UTF-8']]);
|
||||
$client = new Client(['headers' => ['accept' => 'application/json']]);
|
||||
|
||||
}
|
||||
else {
|
||||
// if $responsetype is set to anything else than "json", use the standard request
|
||||
$client = new Client();
|
||||
// $client = new Client(['headers' => ['content-type' => 'text/plain;charset=UTF-8']]);
|
||||
$client = new Client();
|
||||
}
|
||||
|
||||
// echo "Requesting...";
|
||||
$begin = microtime(true);
|
||||
try {
|
||||
$response = $client->request('POST', self::PAYONE_SERVER_API_URL, ['form_params' => $request]);
|
||||
}
|
||||
catch (\GuzzleHttp\Exception\ClientException $e) {
|
||||
$error = $e->getResponse();
|
||||
$responseBodyAsString = $error->getBody()->getContents();
|
||||
MyLog::writeLog(
|
||||
'payone',
|
||||
'error',
|
||||
'Error:1002 Der Zahlungsanbieter ist nicht erreichbar, die Zahlung konnte nicht durchgeführt werden. App\Services\Payone::sendRequest Something went wrong during the HTTP request.',
|
||||
['error' => $error, 'responseBodyAsString' => $responseBodyAsString, 'request' => $request]
|
||||
);
|
||||
abort(403, 'Der Zahlungsanbieter ist nicht erreichbar, die Zahlung konnte nicht durchgeführt werden. Bitte versuchen Sie es später erneut. Fehlercode: 1002');
|
||||
|
||||
if ($response = $client->request('POST', self::PAYONE_SERVER_API_URL, ['form_params' => $request])) {
|
||||
|
||||
if (implode($response->getHeader('Content-Type')) == 'text/plain; charset=UTF-8'){
|
||||
}
|
||||
if (isset($response)) {
|
||||
if (implode($response->getHeader('Content-Type')) == 'text/plain;charset=UTF-8'){
|
||||
// if the content type is text/plain, parse response into array
|
||||
$return = self::parseResponse($response);
|
||||
// \Log::channel('payone')->error('App\Services\Payone::sendRequest content type is text/plain: '.$response);
|
||||
|
||||
} else {
|
||||
// if the content type is anything else, just return the response body
|
||||
$return = $response->getBody();
|
||||
$return = json_decode($response->getBody(),true);
|
||||
MyLog::writeLog(
|
||||
'payone',
|
||||
'error',
|
||||
'Error: App\Services\Payone::sendRequest content type is anything else',
|
||||
['error' => $return, 'response' => $response, 'request' => $request]
|
||||
);
|
||||
}
|
||||
|
||||
} else {
|
||||
MyLog::writeLog(
|
||||
'payone',
|
||||
'error',
|
||||
'Error: App\Services\Payone::sendRequest Something went wrong during the HTTP request',
|
||||
['request' => $request]
|
||||
);
|
||||
throw new Exception('Something went wrong during the HTTP request.');
|
||||
}
|
||||
|
||||
$end = microtime(true);
|
||||
$duration = $end - $begin;
|
||||
if(!is_array($return)){
|
||||
MyLog::writeLog(
|
||||
'payone',
|
||||
'error',
|
||||
'Error: 1003 App\Http\Controllers\Pay\PayoneController::ResponseData response is non array: return:',
|
||||
['return'=>$return, 'response' => $response, 'request' => $request]
|
||||
);
|
||||
abort(403, 'Der Zahlungsanbieter ist nicht erreichbar, die Zahlung konnte nicht durchgeführt werden. Bitte versuchen Sie es später erneut. Fehlercode: 1003');
|
||||
}
|
||||
|
||||
if(!isset($return['status'])){
|
||||
MyLog::writeLog(
|
||||
'payone',
|
||||
'error',
|
||||
'Error: 1004 App\Http\Controllers\Pay\PayoneController::ResponseData response has non status',
|
||||
['return'=>$return, 'response' => $response, 'request' => $request]
|
||||
);
|
||||
abort(403, 'Der Zahlungsanbieter ist nicht erreichbar, die Zahlung konnte nicht durchgeführt werden. Bitte versuchen Sie es später erneut. Fehlercode: 1004');
|
||||
}
|
||||
/* echo "done.\n";
|
||||
echo "Request took " . $duration . " seconds.\n";
|
||||
echo "<br>";
|
||||
echo "Request took " . $duration . " seconds.\n";
|
||||
echo "<br>";
|
||||
*/
|
||||
return $return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,13 @@ namespace App\Services;
|
|||
|
||||
|
||||
use Yard;
|
||||
use App\User;
|
||||
use App\Models\Country;
|
||||
use App\Models\Setting;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Services\dbip\MyDBIP;
|
||||
use App\Models\ShippingCountry;
|
||||
use App\Services\IPinfo\IPinfo;
|
||||
|
||||
class Shop
|
||||
{
|
||||
|
|
@ -117,11 +121,9 @@ class Shop
|
|||
|
||||
Yard::instance('shopping')->setShippingCountryWithPrice($ShippingCountry->id);
|
||||
Yard::instance('shopping')->setUserPriceInfos(Shop::getShopYardInfo());
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function getShopYardInfo(){
|
||||
return [
|
||||
'user_tax_free' => self::$user_tax_free,
|
||||
|
|
@ -131,5 +133,328 @@ class Shop
|
|||
'shipping_country_id' => self::$shipping_country->id,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public static function getYardShoppingItems(){
|
||||
$rows = Yard::instance('shopping')->getContentByOrder();
|
||||
$ret = [];
|
||||
$ret['items'] = [];
|
||||
$is_currency = Yard::instance('shopping')->isPriceCurrency();
|
||||
$tax_free = Yard::instance('shopping')->getUserTaxFree();
|
||||
|
||||
foreach($rows as $row){
|
||||
$product = \App\Models\Product::find($row->id);
|
||||
$item = new \stdClass();
|
||||
$item->image = $row->options->has('image') ? $row->options->image : null;
|
||||
$item->price_net = (float) Yard::instance('shopping')->rowPriceNet($row, 3, '.', '');
|
||||
$item->price_net_total = (float) Yard::instance('shopping')->rowSubtotalNet($row, 2, '.', '');
|
||||
$item->price_currency = $is_currency ? "~".Yard::instance('shopping')->getCurrencyByKey('rowPriceNetCurrency', $row, 3)." ".Yard::instance('shopping')->getPriceCurrencyUnit() : null;
|
||||
$item->price_currency_total = $is_currency ? "~".Yard::instance('shopping')->getCurrencyByKey('rowSubtotalCurrency', $row, 3)." ".Yard::instance('shopping')->getPriceCurrencyUnit() : null;
|
||||
$item->price = $row->price;
|
||||
$item->price_total = ($row->qty * $row->price);
|
||||
$item->qty = $row->qty;
|
||||
$item->name = $product->name;
|
||||
$item->contents = $product->contents;
|
||||
$item->numbers = $product->numbers;
|
||||
$ret['items'][] = $item;
|
||||
}
|
||||
|
||||
$ret['tax_free'] = $tax_free;
|
||||
$ret['total']['subtotal'] = Yard::instance('shopping')->subtotal();
|
||||
$ret['total']['subtotal_currency'] = $is_currency ? "~".Yard::instance('shopping')->getCurrencyByKey('subtotal')." ".Yard::instance('shopping')->getPriceCurrencyUnit() : null;
|
||||
$ret['total']['shippingCountryName'] = Yard::instance('shopping')->getShippingCountryName();
|
||||
$ret['total']['shippingNet'] = Yard::instance('shopping')->shippingNet();
|
||||
$ret['total']['shippingNet currency'] = $is_currency ? "~".Yard::instance('shopping')->getCurrencyByKey('shippingNet')." ".Yard::instance('shopping')->getPriceCurrencyUnit() : null;
|
||||
$ret['total']['subtotalWithShipping'] = Yard::instance('shopping')->subtotalWithShipping();
|
||||
$ret['total']['subtotalWithShipping_currency'] = $is_currency ? "~".Yard::instance('shopping')->getCurrencyByKey('subtotalWithShipping')." ".Yard::instance('shopping')->getPriceCurrencyUnit() : null;
|
||||
$ret['total']['taxWithShipping'] = Yard::instance('shopping')->taxWithShipping();
|
||||
$ret['total']['taxWithShipping_currency'] = $is_currency ? "~".Yard::instance('shopping')->getCurrencyByKey('taxWithShipping')." ".Yard::instance('shopping')->getPriceCurrencyUnit() : null;
|
||||
$ret['total']['totalWithShipping'] = Yard::instance('shopping')->totalWithShipping();
|
||||
$ret['total']['totalWithShipping_currency'] = $is_currency ? "~".Yard::instance('shopping')->getCurrencyByKey('totalWithShipping')." ".Yard::instance('shopping')->getPriceCurrencyUnit() : null;
|
||||
|
||||
|
||||
|
||||
return $ret;
|
||||
}
|
||||
public static function checkShoppingUser($id, $user){
|
||||
if($id === null){
|
||||
abort(403, 'Error: Keine User ID');
|
||||
}
|
||||
$shopping_user = ShoppingUser::findOrFail($id);
|
||||
if($shopping_user->member_id !== $user->id){
|
||||
abort(403, 'Error: Falsche User ID');
|
||||
}
|
||||
$shopping_user = ShoppingUser::findOrFail($id);
|
||||
if($shopping_user->is_like){
|
||||
abort(403, 'Error: Kunde in Prüfung');
|
||||
}
|
||||
return $shopping_user;
|
||||
}
|
||||
|
||||
public static function checkShoppingCountry($for, $id=null){
|
||||
$country_id = null;
|
||||
if($for === 'me' || $for === 'abo-me'){
|
||||
$user = User::find(\Auth::user()->id);
|
||||
if($user->account->same_as_billing){
|
||||
$country_id = $user->account->country_id;
|
||||
}else{
|
||||
$country_id = $user->account->shipping_country_id;
|
||||
}
|
||||
}
|
||||
if(strpos($for, 'ot') !== false && $id){
|
||||
$shopping_user = ShoppingUser::findOrFail($id);
|
||||
if($shopping_user->same_as_billing){
|
||||
$country_id = $shopping_user->billing_country->id;
|
||||
}else{
|
||||
$country_id = $shopping_user->shipping_country->id;
|
||||
}
|
||||
}
|
||||
if($country_id){
|
||||
if($shipping_country = ShippingCountry::whereCountryId($country_id)->first()){
|
||||
if($shipping_country->shipping && $shipping_country->shipping->active){
|
||||
return $shipping_country->id;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getDeliveryCountry($for, $id=null){
|
||||
$country_id = null;
|
||||
if($for === 'me' || $for === 'abo-me'){
|
||||
$user = User::find(\Auth::user()->id);
|
||||
if($user->account->same_as_billing){
|
||||
return $user->account->country ? $user->account->country->getLocated() : '';
|
||||
}else{
|
||||
return $user->account->shipping_country ? $user->account->shipping_country->getLocated() : '';
|
||||
}
|
||||
}
|
||||
if(strpos($for, 'ot') !== false && $id){
|
||||
$shopping_user = ShoppingUser::findOrFail($id);
|
||||
if($shopping_user->same_as_billing){
|
||||
return $shopping_user->billing_country ? $shopping_user->billing_country->getLocated() : '';
|
||||
}else{
|
||||
return $shopping_user->shipping_country ? $shopping_user->shipping_country->getLocated() : '';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
public static function getShippingPriceByShippingCountryId($shipping_country_id, $shipping_weight){
|
||||
$shippingCountry = ShippingCountry::find($shipping_country_id);
|
||||
if(!$shippingCountry){
|
||||
abort(403, 'Fehler: Versandland nicht gefunden');
|
||||
}
|
||||
if(!isset($shippingCountry->shipping) && count($shippingCountry->shipping->shipping_prices) === 0){
|
||||
abort(403, 'Fehler: Kein Preise für das Versandland angelegt');
|
||||
}
|
||||
$shipping_price = $shippingCountry->shipping->shipping_prices->first();
|
||||
if(!$shipping_price){
|
||||
abort(403, 'Fehler: Preis vom Versandland nicht gefunden');
|
||||
}
|
||||
|
||||
/*if(!$shipping_weight){
|
||||
abort(403, 'Fehler: Kein Versandgewicht');
|
||||
}*/
|
||||
|
||||
if($shipping_weight == 0){
|
||||
$shipping_price->price = 0;
|
||||
$shipping_price->price_comp = 0;
|
||||
return $shipping_price;
|
||||
}
|
||||
|
||||
if($shipping_weight > 0){
|
||||
/*
|
||||
if($this->shipping_free && $this->total(2, '.', '') >= $this->shipping_free){
|
||||
if($this->weightByFreeShipping() == 0){
|
||||
$shipping_price->price = 0;
|
||||
$shipping_price->price_comp = 0;
|
||||
}else{
|
||||
$shipping_price = $this->shippingPriceByWeight($shipping->shipping_prices, $this->weightByFreeShipping());
|
||||
}
|
||||
|
||||
}else{
|
||||
*/
|
||||
|
||||
return self::shippingPriceByWeight($shippingCountry->shipping->shipping_prices, $shipping_weight);
|
||||
}
|
||||
/*if($this->weight() == 0){
|
||||
|
||||
}else{
|
||||
|
||||
$shipping_price = $this->shippingPriceByWeight($shipping->shipping_prices, $this->weight());
|
||||
//first by price
|
||||
//$shipping_price = $this->shippingPriceByTotal($shipping->shipping_prices, $this->total(2, '.', ''));
|
||||
//sec by weight
|
||||
//if(!$shipping_price){
|
||||
//}
|
||||
}
|
||||
//default
|
||||
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
public static function shippingPriceByWeight($shipping_prices, $shipping_weight){
|
||||
foreach ($shipping_prices as $price){
|
||||
if($price->weight_from > 0 && $price->weight_to > 0){
|
||||
if($shipping_weight >= $price->weight_from && $shipping_weight <= $price->weight_to){
|
||||
return $price;
|
||||
}
|
||||
}
|
||||
}
|
||||
abort(403, 'Fehler: Preis nach Gewicht im Versandland nicht gefunden');
|
||||
}
|
||||
|
||||
public static function isCompProducts($for){
|
||||
/*
|
||||
$for = me, ot-member, ot-customer, abo-ot-member, abo-ot-customer, abo-me
|
||||
*/
|
||||
if($for === 'me'){
|
||||
return (bool) Setting::getContentBySlug('is_comp_me_order');
|
||||
}
|
||||
if($for === 'abo-me'){
|
||||
return (bool) Setting::getContentBySlug('is_comp_me_abo');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getIPDatabaseInfo(){
|
||||
|
||||
//first check the DBs for the IP
|
||||
|
||||
|
||||
/* testing
|
||||
|
||||
foreach(self::testIps() as $ip_address){
|
||||
$country = MyDBIP::lookup($ip_address);
|
||||
dump($country);
|
||||
if($country !== false){
|
||||
continue;
|
||||
//return strtolower($country);
|
||||
}
|
||||
dump("not found ".$ip_address);
|
||||
//not found search in IPinfo
|
||||
$access_token = 'e1054aa11daf1e';
|
||||
$client = new IPinfo($access_token);
|
||||
|
||||
$details = $client->getDetails($ip_address);
|
||||
if(isset($details->error) && $details->error !== null){
|
||||
//return 'error';
|
||||
dump("not foun on IPinfo ".$details->error);
|
||||
}
|
||||
if(isset($details->country) && $details->country !== null){
|
||||
MyDBIP::insert($ip_address, $details->country);
|
||||
dump("found on IPinfo ".$details->country);
|
||||
//return strtolower($details->country);
|
||||
}
|
||||
//return 'error';
|
||||
}
|
||||
|
||||
dd("done");
|
||||
*/
|
||||
|
||||
/* live */
|
||||
|
||||
$ip_address = \Request::ip();
|
||||
// $ip_address = '86.189.47.78'; //testing
|
||||
$country = MyDBIP::lookup($ip_address);
|
||||
if($country !== false){
|
||||
return strtolower($country);
|
||||
}
|
||||
//not found search in IPinfo
|
||||
$access_token = 'e1054aa11daf1e';
|
||||
$client = new IPinfo($access_token);
|
||||
|
||||
$details = $client->getDetails($ip_address);
|
||||
if(isset($details->error) && $details->error !== null){
|
||||
return 'error';
|
||||
}
|
||||
if(isset($details->country) && $details->country !== null){
|
||||
MyDBIP::insert($ip_address, $details->country);
|
||||
return strtolower($details->country);
|
||||
}
|
||||
return 'error';
|
||||
}
|
||||
|
||||
|
||||
private static function testIps(){
|
||||
return [
|
||||
'58.217.40.197'
|
||||
,'207.117.144.54'
|
||||
,'65.169.228.128'
|
||||
,'6.84.3.236'
|
||||
,'214.56.36.93'
|
||||
,'9.43.145.245'
|
||||
,'231.199.26.76'
|
||||
,'86.189.47.78'
|
||||
,'3.122.58.75'
|
||||
,'251.133.143.149'
|
||||
,'6.142.181.83'
|
||||
,'2.55.191.86'
|
||||
,'90.189.58.233'
|
||||
,'57.3.139.111'
|
||||
,'41.130.99.194'
|
||||
,'1.59.123.14'
|
||||
,'9.119.131.109'
|
||||
,'54.240.231.9'
|
||||
,'117.19.131.144'
|
||||
,'221.217.39.211'
|
||||
,'7.43.125.76'
|
||||
,'224.86.233.79'
|
||||
,'32.151.38.98'
|
||||
,'4.134.40.92'
|
||||
,'4.70.188.58'
|
||||
,'24.7.152.228'
|
||||
,'58.122.179.1'
|
||||
,'5.123.9.44'
|
||||
,'3.175.206.5'
|
||||
,'8.142.119.47'
|
||||
,'40.248.58.203'
|
||||
,'7.84.254.187'
|
||||
,'215.215.239.71'
|
||||
,'124.40.66.196'
|
||||
,'215.87.143.102'
|
||||
,'143.39.97.13'
|
||||
,'202.56.79.198'
|
||||
,'143.60.125.142'
|
||||
,'73.233.153.126'
|
||||
,'121.144.28.245'
|
||||
,'53.232.193.122'
|
||||
,'104.222.102.209'
|
||||
,'216.55.215.13'
|
||||
,'84.106.145.239'
|
||||
,'200.131.52.20'
|
||||
,'132.252.158.0'
|
||||
,'220.11.129.27'
|
||||
,'8.153.0.186'
|
||||
,'119.206.117.107'
|
||||
,'222.93.42.133'
|
||||
,'105.104.224.98'
|
||||
,'252.156.181.78'
|
||||
,'7.139.235.187'
|
||||
,'111.140.127.91'
|
||||
,'1.186.17.84'
|
||||
,'85.59.39.221'
|
||||
,'231.152.252.43'
|
||||
,'125.214.216.123'
|
||||
,'69.31.65.238'
|
||||
,'126.12.105.55'
|
||||
,'211.39.4.118'
|
||||
,'73.102.88.79'
|
||||
,'210.229.38.137'
|
||||
,'5.3.230.214'
|
||||
,'208.92.91.242'
|
||||
,'4.105.177.199'
|
||||
,'38.10.48.92'
|
||||
,'133.33.44.13'
|
||||
,'202.189.24.255'
|
||||
,'5.101.244.234'
|
||||
,'2.52.110.194'
|
||||
,'1.130.73.146'
|
||||
,'84.237.232.120'
|
||||
,'25.163.83.194'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -79,8 +79,8 @@ class ShopApiOrderCart
|
|||
|
||||
//only for tax split / tax and price on calculate function
|
||||
|
||||
$this->shoppingCollectOrder->addTaxToSplit($tax_rate, $user_tax_qty);
|
||||
$this->shoppingCollectOrder->addNetToSplit($tax_rate, $user_price_net_qty);
|
||||
$this->shoppingCollectOrder->addTaxToSplit((int)$tax_rate, (float)$user_tax_qty);
|
||||
$this->shoppingCollectOrder->addNetToSplit((int)$tax_rate, (float)$user_price_net_qty);
|
||||
$this->shoppingCollectOrder->tax_total += $user_tax_qty;
|
||||
$this->shoppingCollectOrder->price_total_net += $user_price_net_qty;
|
||||
$this->shoppingCollectOrder->points += ($item->points * $item->qty);
|
||||
|
|
|
|||
102
app/Services/SyS/CleanHTMLProductDescription.php
Normal file
102
app/Services/SyS/CleanHTMLProductDescription.php
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use App\Models\Product;
|
||||
use Request;
|
||||
use App\Models\TransProduct;
|
||||
use App\Models\UserCreditItem;
|
||||
|
||||
class CleanHTMLProductDescription
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
dump("CleanHTMLProductDescription");
|
||||
// dd('check function');
|
||||
$TransProducts = TransProduct::limit(2000)->get();
|
||||
dump(count($TransProducts));
|
||||
$c = 0;
|
||||
foreach($TransProducts as $item){
|
||||
if($item->value){
|
||||
$item->value = self::cleanHTML($item->value);
|
||||
$item->save();
|
||||
|
||||
//dump($item->value);
|
||||
$c++;
|
||||
}
|
||||
}
|
||||
dump("counter TransProduct");
|
||||
dump($c);
|
||||
|
||||
$Products = Product::limit(2000)->get();
|
||||
dump(count($Products));
|
||||
$c = 0;
|
||||
foreach($Products as $item){
|
||||
if($item){
|
||||
$item->copy = self::cleanHTML($item->copy);
|
||||
$item->description = self::cleanHTML($item->description);
|
||||
$item->usage = self::cleanHTML($item->usage);
|
||||
$item->ingredients = self::cleanHTML($item->ingredients);
|
||||
|
||||
$item->save();
|
||||
|
||||
//dump($item->value);
|
||||
$c++;
|
||||
}
|
||||
}
|
||||
|
||||
dump("counter");
|
||||
dd($c);
|
||||
}
|
||||
|
||||
public static function cleanHTML($html)
|
||||
{
|
||||
// $html = preg_replace("/(</?)div/", "$1p", $html);
|
||||
|
||||
$html = str_replace('<p> </p>', '', $html);
|
||||
$html = str_replace('<p></p>', '', $html);
|
||||
$html = str_replace('<p><br></p>', '', $html);
|
||||
$html = str_replace('<p><br></p>', '', $html);
|
||||
|
||||
$html = str_replace('<br>', '', $html);
|
||||
$html = str_replace('text -primary', 'text-primary', $html);
|
||||
$html = str_replace('fa -check', 'fa-check', $html);
|
||||
$html = str_replace('text- primary', 'text-primary', $html);
|
||||
$html = str_replace('fa- check', 'fa-check', $html);
|
||||
$html = str_replace('<ul class="list-unstyled list-icons" style="padding-left: 15px;"> </ul>', '', $html);
|
||||
|
||||
$html = str_replace('</span>', '', $html);
|
||||
$html = preg_replace('/(<[^>]+) style=".*?"/i', '$1', $html);
|
||||
|
||||
$html = str_replace('<li></li>', '', $html);
|
||||
$html = str_replace('<li> </li>', '', $html);
|
||||
$html = str_replace('< i', '<i', $html);
|
||||
$html = str_replace('< li>', '<li>', $html);
|
||||
|
||||
$html = str_replace('</ i>', '</i>', $html);
|
||||
$html = str_replace('</ li>', '</li>', $html);
|
||||
|
||||
$html = str_replace('</ b>', '</b>', $html);
|
||||
$html = str_replace('< /b>', '</b>', $html);
|
||||
|
||||
$html = str_replace('</ p>', '</p>', $html);
|
||||
$html = str_replace('< /p>', '</p>', $html);
|
||||
|
||||
$html = str_replace('< /i>', '</i>', $html);
|
||||
$html = str_replace('< /li>', '</li>', $html);
|
||||
$html = str_replace('<div>', '', $html);
|
||||
$html = str_replace('</div>', '', $html);
|
||||
$html = str_replace('>>', '>', $html);
|
||||
return $html;
|
||||
|
||||
}
|
||||
|
||||
public static function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
\Session()->flash('alert-save', true);
|
||||
return back();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ namespace App\Services\SyS;
|
|||
|
||||
use Request;
|
||||
|
||||
class Cronjobs
|
||||
class CronJobs
|
||||
{
|
||||
|
||||
public static function show()
|
||||
|
|
|
|||
|
|
@ -18,19 +18,29 @@ class DomainSSL
|
|||
//$domain = 'mivita.care';
|
||||
// $ssl = KasSLLController::getApiSSLParameter();
|
||||
$SubDomains = [];
|
||||
|
||||
$get_subdomains = $kas->action('get_subdomains');
|
||||
foreach ($get_subdomains as $subdomain){
|
||||
if(isset($subdomain['subdomain_name'])){
|
||||
if(strpos($subdomain['subdomain_name'], 'www.') !== false){
|
||||
continue;
|
||||
}
|
||||
if(strpos($subdomain['subdomain_name'], 'api.') !== false){
|
||||
continue;
|
||||
}
|
||||
if(strpos($subdomain['subdomain_name'], 'checkout.') !== false){
|
||||
continue;
|
||||
}
|
||||
$SubDomains[$subdomain['subdomain_name']] =
|
||||
[
|
||||
'ssl_certificate_sni' => $subdomain['ssl_certificate_sni'],
|
||||
'php_version' => $subdomain['php_version'],
|
||||
];
|
||||
|
||||
if(strpos($subdomain['subdomain_name'], 'www.') !== false){
|
||||
continue;
|
||||
}else{
|
||||
@dump($subdomain);
|
||||
}
|
||||
if(strpos($subdomain['subdomain_name'], 'api.') !== false){
|
||||
continue;
|
||||
}
|
||||
if(strpos($subdomain['subdomain_name'], 'checkout.') !== false){
|
||||
continue;
|
||||
}
|
||||
$SubDomains[$subdomain['subdomain_name']] = $subdomain['ssl_certificate_sni'];
|
||||
|
||||
|
||||
/* if($subdomain['ssl_certificate_sni'] !== "Y"){
|
||||
$pra = array(
|
||||
|
|
@ -50,19 +60,32 @@ class DomainSSL
|
|||
|
||||
//$text .= "\n";
|
||||
}
|
||||
|
||||
$dobbleDomains = [];
|
||||
|
||||
foreach($user_shops as $user_shop){
|
||||
$user_shop->hasSubdomain = false;
|
||||
$user_shop->hasSSL = false;
|
||||
$user_shop->PHPversion = "";
|
||||
if(array_key_exists($user_shop->slug.'.mivita.care', $SubDomains)){
|
||||
$user_shop->hasSubdomain = true;
|
||||
$user_shop->hasSSL = $SubDomains[$user_shop->slug.'.mivita.care'] === 'Y' ? true : false;
|
||||
$user_shop->hasSSL = $SubDomains[$user_shop->slug.'.mivita.care']['ssl_certificate_sni'] === 'Y' ? true : false;
|
||||
$user_shop->PHPversion = $SubDomains[$user_shop->slug.'.mivita.care']['php_version'];
|
||||
unset($SubDomains[$user_shop->slug.'.mivita.care']);
|
||||
}
|
||||
$dobbleDomains[$user_shop->user_id][$user_shop->id] = $user_shop->slug.'.mivita.care';
|
||||
}
|
||||
foreach($dobbleDomains as $key => $dobbleDomain){
|
||||
if(count($dobbleDomain) === 1){
|
||||
unset($dobbleDomains[$key]);
|
||||
}
|
||||
}
|
||||
$data = [
|
||||
'values' => $user_shops,
|
||||
'text' => $text,
|
||||
'SubDomains' => $SubDomains,
|
||||
'dobbleDomains' => $dobbleDomains,
|
||||
|
||||
];
|
||||
|
||||
return view('sys.tools.domain-ssl', $data);
|
||||
|
|
@ -98,16 +121,22 @@ class DomainSSL
|
|||
}
|
||||
|
||||
if(isset($data['update_ssl'])){
|
||||
|
||||
//prüfen ob subdomain existiert
|
||||
$user_shop = UserShop::findOrFail($data['update_ssl']);
|
||||
$subdomain_name = $user_shop->slug.'.mivita.care';
|
||||
|
||||
$kas = new KasController();
|
||||
$ssl = KasSLLController::getApiSSLParameter();
|
||||
$pra = array(
|
||||
'hostname' => $subdomain_name
|
||||
);
|
||||
$pra = array_merge($pra, $ssl);
|
||||
$value = $kas->action('update_ssl', $pra);
|
||||
\Session()->flash('alert-success', 'update SSL: '.$value.'');
|
||||
$subdomain = $kas->action('get_subdomains', ['subdomain_name' => $subdomain_name]);
|
||||
if(!isset($subdomain[0]['subdomain_name'])){ //not found
|
||||
self::makeNewSubDomain($user_shop->slug);
|
||||
\Session()->flash('alert-danger', 'subdomain: '.$subdomain_name.' nicht gefunden');
|
||||
return back();
|
||||
}else{
|
||||
self::updateSubDomain($subdomain_name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -115,4 +144,55 @@ class DomainSSL
|
|||
return back();
|
||||
}
|
||||
|
||||
private static function updateSubDomain($subdomain_name){
|
||||
|
||||
$kas = new KasController();
|
||||
$ssl = KasSLLController::getApiSSLParameter();
|
||||
$pra = array(
|
||||
'hostname' => $subdomain_name
|
||||
);
|
||||
$pra = array_merge($pra, $ssl);
|
||||
$value = $kas->action('update_ssl', $pra);
|
||||
\Session()->flash('alert-success', 'update SSL: '.$value.'');
|
||||
return $value;
|
||||
}
|
||||
|
||||
private static function makeNewSubDomain($slug){
|
||||
|
||||
$kas = new KasController();
|
||||
$domain = 'mivita.care';
|
||||
|
||||
//check if exisist
|
||||
$subdomains = $kas->action('get_subdomains');
|
||||
foreach ($subdomains as $subdomain){
|
||||
if(!isset($subdomain['subdomain_name'])){
|
||||
continue;
|
||||
}
|
||||
$sub = str_replace(".".$domain, '', $subdomain['subdomain_name']);
|
||||
if($sub == $slug){
|
||||
\Session()->flash('alert-danger', __('shop.error_subdomain_exists'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//add
|
||||
$full_subdomain_name = $slug.".".$domain;
|
||||
$pra = array(
|
||||
'subdomain_name' => $slug,
|
||||
'domain_name' => $domain,
|
||||
'subdomain_path' => '/mein.mivita.care/public/',
|
||||
'php_version' => config('app.php_version'),
|
||||
//'ssl_proxy' => 'Y',
|
||||
//'redirect_status' => 0
|
||||
);
|
||||
$add_subdomain = $kas->action('add_subdomain', $pra);
|
||||
if($add_subdomain == $full_subdomain_name){
|
||||
\Session()->flash('alert-success', 'Add Subdomain: '.$add_subdomain.'');
|
||||
return $add_subdomain;
|
||||
}
|
||||
\Session()->flash('alert-danger', 'Fehler: '.$add_subdomain.'');
|
||||
return $add_subdomain;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
84
app/Services/SyS/ImportDbipCountry.php
Normal file
84
app/Services/SyS/ImportDbipCountry.php
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use App\Models\DbipLookup;
|
||||
use App\Services\dbip\DBIP;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Request;
|
||||
|
||||
class ImportDbipCountry
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
dump("ImportDbipCountry");
|
||||
// dd('check function');
|
||||
|
||||
|
||||
self::read('dbip-country-lite-2024-07.csv', 0, 0);
|
||||
$c = 0;
|
||||
dump("okay counter");
|
||||
dd($c);
|
||||
|
||||
}
|
||||
|
||||
public static function read($filename, $skip = 0, $limit = 0)
|
||||
{
|
||||
/*$find = inet_pton("1.10.128.0");
|
||||
dump($find);
|
||||
dd(DbipLookup::where('ip_start', "<=", $find)->orderBy('ip_start', 'desc')->first());
|
||||
if(!Storage::disk('import')->has($filename)){
|
||||
die("File not found in import folder: ".$filename);
|
||||
}*/
|
||||
|
||||
$path = Storage::disk('import')->path($filename);
|
||||
$fileContents = file($path);
|
||||
$c = 0;
|
||||
foreach ($fileContents as $line) {
|
||||
$row = str_getcsv($line);
|
||||
$row[] = self::addrType($row[0]);
|
||||
|
||||
|
||||
//
|
||||
//base64_encode(file_get_contents($path))
|
||||
// dump($row);
|
||||
\DB::table('dbip_lookup')->insert([
|
||||
'ip_start' => inet_pton($row[0]),
|
||||
'ip_end' => inet_pton($row[1]),
|
||||
'country' => $row[2],
|
||||
'addr_type' => $row[3]
|
||||
]);
|
||||
|
||||
|
||||
//dump(inet_pton($row[0]));
|
||||
/* DbipLookup::create([
|
||||
'ip_start' => ,
|
||||
'ip_end' => inet_pton($row[1]),
|
||||
'country' => $row[2],
|
||||
'addr_type' => $row[3]
|
||||
]);*/
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
private static function addrType($addr) {
|
||||
if (ip2long($addr) !== false) {
|
||||
return "ipv4";
|
||||
} else if (preg_match('/^[0-9a-fA-F:]+$/', $addr) && @inet_pton($addr)) {
|
||||
return "ipv6";
|
||||
}
|
||||
die("unknown address type for {$addr}");
|
||||
}
|
||||
|
||||
public static function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
\Session()->flash('alert-save', true);
|
||||
return back();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
45
app/Services/SyS/RepairSalesVolumeInvoice.php
Normal file
45
app/Services/SyS/RepairSalesVolumeInvoice.php
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use Request;
|
||||
use App\Models\UserBusiness;
|
||||
use App\Models\UserInvoice;
|
||||
use App\Models\UserSalesVolume;
|
||||
|
||||
class RepairSalesVolumeInvoice
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
|
||||
dump("RepairSalesVolumeInvoice");
|
||||
dd('check function');
|
||||
$UserSalesVolumes = UserSalesVolume::where('status', '<', 3)->where('user_invoice_id', null)->orderBy('id', 'desc')->limit(1000)->get();
|
||||
dump(count($UserSalesVolumes));
|
||||
$c = 0;
|
||||
foreach($UserSalesVolumes as $user_sales_volume){
|
||||
|
||||
if($user_sales_volume->shopping_order_id){
|
||||
$UserInvoice = UserInvoice::where('shopping_order_id', $user_sales_volume->shopping_order_id)->first();
|
||||
if($UserInvoice){
|
||||
$user_sales_volume->user_invoice_id = $UserInvoice->id;
|
||||
$user_sales_volume->save();
|
||||
$c++;
|
||||
}
|
||||
}
|
||||
}
|
||||
dump("counter");
|
||||
dd($c);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
\Session()->flash('alert-save', true);
|
||||
return back();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
48
app/Services/SyS/UserCreditItemsAddFrom.php
Normal file
48
app/Services/SyS/UserCreditItemsAddFrom.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use Request;
|
||||
use Carbon;
|
||||
use App\Models\SySetting;
|
||||
use App\Models\ShoppingOrder;
|
||||
use App\Models\UserCreditItem;
|
||||
use App\User;
|
||||
|
||||
class UserCreditItemsAddFrom
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
UserCreditItem::all()->each(function($item){
|
||||
$date = self::getExplodeMessage($item);
|
||||
$item->from_month = $date['n'];
|
||||
$item->from_year = $date['Y'];
|
||||
$item->save();
|
||||
});
|
||||
dd("done");
|
||||
}
|
||||
|
||||
|
||||
private static function getExplodeMessage($item){
|
||||
$date = [];
|
||||
if(strpos($item->message, '#')){
|
||||
$em = explode("#", $item->message);
|
||||
|
||||
if(isset($em[1])){ //month
|
||||
$data['n'] =$em[1];
|
||||
}
|
||||
if(isset($em[2])){ //year
|
||||
$data['Y'] =$em[2];
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
public static function store()
|
||||
{
|
||||
abort(403, 'STOP funtion not online');
|
||||
dd("");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
88
app/Services/SyS/UserCreditItemsChangeMessage.php
Normal file
88
app/Services/SyS/UserCreditItemsChangeMessage.php
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
namespace App\Services\SyS;
|
||||
|
||||
use Request;
|
||||
use App\Models\UserBusiness;
|
||||
use App\Models\UserCreditItem;
|
||||
use App\Models\UserInvoice;
|
||||
use App\Models\UserSalesVolume;
|
||||
|
||||
class UserCreditItemsChangeMessage
|
||||
{
|
||||
|
||||
public static function show()
|
||||
{
|
||||
|
||||
dump("UserCreditItemsChangeMessage");
|
||||
dd('check function');
|
||||
$UserCreditItems = UserCreditItem::orderBy('id', 'desc')->limit(1000)->get();
|
||||
dump(count($UserCreditItems));
|
||||
$c = 0;
|
||||
foreach($UserCreditItems as $item){
|
||||
if($item->message){
|
||||
$item->message = self::convertMessage($item->message);
|
||||
$item->save();
|
||||
$c++;
|
||||
}
|
||||
}
|
||||
dump("counter");
|
||||
dd($c);
|
||||
}
|
||||
|
||||
public static function convertMessage($message){
|
||||
$months = [
|
||||
'Januar' => "1#",
|
||||
'Februar' => "2#",
|
||||
'März' => "3#",
|
||||
'April' => "4#",
|
||||
'Mai' => "5#",
|
||||
'Juni' => "6#",
|
||||
'Juli' => "7#",
|
||||
'August' => "8#",
|
||||
'September' => "9#",
|
||||
'Oktober' => "10#",
|
||||
'November' => "11#",
|
||||
'Dezember' => "12#",
|
||||
];
|
||||
|
||||
$em = explode(" ", $message);
|
||||
$new_message = "";
|
||||
if($em[0] === "Provision"){
|
||||
switch ($em[1]) {
|
||||
case 'Shop':
|
||||
$new_message .= 'payment.commission_shop#';
|
||||
break;
|
||||
case 'Team':
|
||||
$new_message .= 'payment.commission_team#';
|
||||
break;
|
||||
case 'Payline':
|
||||
$new_message .= 'payment.commission_payline#';
|
||||
break;
|
||||
case 'Wachstumsbonus':
|
||||
$new_message .= 'payment.commission_growth_bonus#';
|
||||
break;
|
||||
default:
|
||||
dd("Error: ".$message);
|
||||
break;
|
||||
}
|
||||
|
||||
if(isset($months[$em[2]])){
|
||||
$new_message .= $months[$em[2]];
|
||||
}
|
||||
$new_message .= $em[3];
|
||||
return $new_message;
|
||||
}
|
||||
|
||||
return $message;
|
||||
|
||||
}
|
||||
|
||||
public static function store()
|
||||
{
|
||||
$data = Request::all();
|
||||
\Session()->flash('alert-save', true);
|
||||
return back();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -69,9 +69,7 @@ class SysLog
|
|||
}
|
||||
}
|
||||
|
||||
public function getLevelType(){
|
||||
return $this->levelTypes[$this->log->level];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
17
app/Services/TranslationHelper.php
Normal file
17
app/Services/TranslationHelper.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Models\UserLevel;
|
||||
|
||||
class TranslationHelper
|
||||
{
|
||||
|
||||
|
||||
|
||||
public static function transUserLevelName($name){
|
||||
$UserLevel = UserLevel::whereName($name)->first();
|
||||
return $UserLevel ? $UserLevel->getLang('name') : $name;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
|
||||
use Yard;
|
||||
use App\User;
|
||||
use App\Models\ShippingCountry;
|
||||
|
||||
|
|
@ -9,18 +9,57 @@ class UserService
|
|||
{
|
||||
public static $user_country;
|
||||
public static $shipping_country;
|
||||
public static $user_tax_free;
|
||||
public static $shipping_free = false;
|
||||
public static $user_tax_free = false;
|
||||
public static $user_reverse_charge = false;
|
||||
|
||||
|
||||
|
||||
public static function getTransChange(){
|
||||
|
||||
$langs = config('localization.supportedLocales');
|
||||
$ret = [];
|
||||
foreach($langs as $code => $lang){
|
||||
$ret[strtolower($code)] = strtolower($lang['native']);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
public static function initCustomerYard($shopping_user, $for){
|
||||
self::$user_tax_free = false;
|
||||
if($shopping_user->same_as_billing){
|
||||
self::$user_country = $shopping_user->billing_country;
|
||||
self::$shipping_country = $shopping_user->billing_country;
|
||||
}else{
|
||||
self::$user_country = $shopping_user->billing_country;
|
||||
self::$shipping_country = $shopping_user->shipping_country;
|
||||
}
|
||||
if(self::$user_country->supply_country && self::$shipping_country->supply_country){
|
||||
self::$user_tax_free = true;
|
||||
}
|
||||
$ShippingCountry = ShippingCountry::whereCountryId(self::$shipping_country->id)->first();
|
||||
self::$shipping_free = $ShippingCountry->shipping ? $ShippingCountry->shipping->free : false;
|
||||
self::$shipping_free = self::$shipping_free !== null ? self::$shipping_free : false;
|
||||
Yard::instance('shopping')->setShippingCountryWithPrice($ShippingCountry->id, $for);
|
||||
Yard::instance('shopping')->setUserPriceInfos(self::getYardInfo());
|
||||
}
|
||||
|
||||
public static function initUserYard(User $user, $shipping_country_id, $for){
|
||||
self::$shipping_free = false;
|
||||
self::checkUserTaxShippingCountry($user, $shipping_country_id,);
|
||||
Yard::instance('shopping')->setShippingCountryWithPrice($shipping_country_id, $for);
|
||||
Yard::instance('shopping')->setUserPriceInfos(self::getYardInfo());
|
||||
}
|
||||
|
||||
|
||||
public static function checkUserTaxShippingCountry(User $user, $shipping_country_id) {
|
||||
|
||||
if(!$user->account && !$user->account->country_id){
|
||||
if(!$user->account || !$user->account->country_id){
|
||||
abort(403, 'Error: User hat kein Land!');
|
||||
}
|
||||
$ShippingCountry = ShippingCountry::findOrFail($shipping_country_id);
|
||||
self::$user_tax_free = self::performUserTaxShippingCountry($user, $ShippingCountry);
|
||||
|
||||
return $ShippingCountry;
|
||||
/*
|
||||
dump( self::$user_price_code );
|
||||
dump( self::$user_tax_free );
|
||||
|
|
@ -54,13 +93,12 @@ class UserService
|
|||
}
|
||||
}
|
||||
//Lieferland ohne RSV
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getYardInfo(){
|
||||
return [
|
||||
'shipping_free' => false,
|
||||
'shipping_free' => self::$shipping_free,
|
||||
'user_tax_free' => self::$user_tax_free,
|
||||
'user_reverse_charge' => self::$user_reverse_charge,
|
||||
'user_country_id' => self::$user_country->id,
|
||||
|
|
@ -81,7 +119,9 @@ class UserService
|
|||
}
|
||||
|
||||
public static function getOrderInfo($key = false){
|
||||
|
||||
if(!self::$user_country){
|
||||
return '';
|
||||
}
|
||||
switch ($key) {
|
||||
case 'billing_state':
|
||||
return self::$user_country->getLocated();
|
||||
|
|
@ -90,10 +130,10 @@ class UserService
|
|||
return self::$shipping_country->getLocated();
|
||||
break;
|
||||
case 'tax_free':
|
||||
return self::$user_tax_free ? 'Nein' : 'Ja';
|
||||
return self::$user_tax_free ? __('no') : __('yes');
|
||||
break;
|
||||
case 'user_reverse_charge':
|
||||
return self::$user_reverse_charge ? 'Ja' : 'Nein';
|
||||
return self::$user_reverse_charge ? __('yes') : __('no');
|
||||
break;
|
||||
|
||||
}
|
||||
|
|
|
|||
230
app/Services/UserUtil.php
Normal file
230
app/Services/UserUtil.php
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
|
||||
use App\User;
|
||||
use App\Models\ShoppingUser;
|
||||
use App\Models\UserCleanUpLog;
|
||||
use App\Models\ShoppingUserMemberLog;
|
||||
use App\Http\Controllers\Api\KasController;
|
||||
|
||||
class UserUtil
|
||||
{
|
||||
|
||||
|
||||
public static function setShoppingUserToNewMember($pre_member_id, $new_member_id)
|
||||
{
|
||||
$ShoppingUsers = ShoppingUser::where('member_id', $pre_member_id)->get();
|
||||
foreach($ShoppingUsers as $shopping_user){
|
||||
ShoppingUserMemberLog::create([
|
||||
'pre_member_id' => $shopping_user->member_id,
|
||||
'shopping_user_id' => $shopping_user->id,
|
||||
'new_member_id' => $new_member_id
|
||||
]);
|
||||
$shopping_user->member_id = $new_member_id;
|
||||
$shopping_user->save();
|
||||
}
|
||||
}
|
||||
|
||||
public static function setNewSponsorToChilds($inactive_sponsor_id, $new_sponsor_id){
|
||||
//alle User die diesen inaktivien Sponsor haben
|
||||
$child_users = User::where('m_sponsor', $inactive_sponsor_id)->get(); //auch deaktiverte
|
||||
foreach($child_users as $child_user){
|
||||
UserCleanUpLog::create([
|
||||
'inactive_sponsor_id' => $inactive_sponsor_id,
|
||||
'child_user_id' => $child_user->id,
|
||||
'new_sponsor_id' => $new_sponsor_id,
|
||||
]);
|
||||
$child_user->m_sponsor = $new_sponsor_id;
|
||||
$child_user->save();
|
||||
}
|
||||
}
|
||||
|
||||
public static function resetChildsToSponsor($re_sponsor_id){
|
||||
//alle alten Childs vom re_sponsor_id / User wieder herstellen
|
||||
$UserCleanUpUsers = UserCleanUpLog::where('inactive_sponsor_id', $re_sponsor_id)->get();
|
||||
foreach($UserCleanUpUsers as $UserCleanUpUser){
|
||||
$child_user = User::find($UserCleanUpUser->child_user_id);
|
||||
if($child_user){
|
||||
//delete Logs from user child where is newer then this
|
||||
$deleteUserCleanUpLogs = UserCleanUpLog::where('child_user_id', $UserCleanUpUser->child_user_id)->where('created_at', '>', $UserCleanUpUser->created_at)->get();
|
||||
foreach($deleteUserCleanUpLogs as $deleteUserCleanUpLog){
|
||||
$deleteUserCleanUpLog->delete();
|
||||
}
|
||||
if($child_user->m_sponsor){ // child is active
|
||||
$child_user->m_sponsor = $re_sponsor_id;
|
||||
}
|
||||
if($child_user->pre_sponsor){ //child is inactive
|
||||
$child_user->pre_sponsor = $re_sponsor_id;
|
||||
}
|
||||
$child_user->save();
|
||||
//delete this log
|
||||
$UserCleanUpUser->delete();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function setUserToClient($user_id, $sponsor_id){
|
||||
$user = User::find($user_id);
|
||||
|
||||
if($user){
|
||||
$data = [
|
||||
'member_id' => $sponsor_id,
|
||||
'language' => $user->lang ? $user->lang : 'de',
|
||||
'billing_salutation' => $user->account->salutation,
|
||||
'billing_company' => $user->account->company,
|
||||
'billing_firstname' => $user->account->first_name,
|
||||
'billing_lastname' => $user->account->last_name,
|
||||
'billing_address' => $user->account->address,
|
||||
'billing_address_2' => $user->account->address_2,
|
||||
'billing_zipcode' => $user->account->zipcode,
|
||||
'billing_city' => $user->account->city,
|
||||
'billing_country_id' => $user->account->country_id,
|
||||
'billing_phone' => $user->account->getPhoneNumber(),
|
||||
'billing_email' => $user->email,
|
||||
'same_as_billing' => $user->account->same_as_billing,
|
||||
'shipping_salutation' => $user->account->shipping_salutation,
|
||||
'shipping_company' => $user->account->shipping_company,
|
||||
'shipping_firstname' => $user->account->shipping_firstname,
|
||||
'shipping_lastname' => $user->account->shipping_lastname,
|
||||
'shipping_address' => $user->account->shipping_address,
|
||||
'shipping_address_2' => $user->account->shipping_address_2,
|
||||
'shipping_zipcode' => $user->account->shipping_zipcode,
|
||||
'shipping_city' => $user->account->shipping_city,
|
||||
'shipping_country_id' => $user->account->shipping_country_id,
|
||||
'shipping_phone' => $user->account->getShippingPhoneFull(),
|
||||
];
|
||||
ShoppingUser::create($data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
find next activ sponsor on user id
|
||||
first $sponsor_id can user_id, looks has m_sponsor or pre_sponsor.
|
||||
*/
|
||||
public static function findNextActiveSponsor($sponsor_id){
|
||||
|
||||
$user = User::withTrashed()->find($sponsor_id);
|
||||
if(!$user){ //kein User unter der ID - to root
|
||||
return User::find(6);
|
||||
}
|
||||
//user ist aktiv
|
||||
if($user->isActiveAccount()){
|
||||
return $user;
|
||||
}
|
||||
if($user->m_sponsor){ //hat der User einen m_sponsor
|
||||
return self::findNextActiveSponsor($user->m_sponsor);
|
||||
}
|
||||
if($user->pre_sponsor){ //hat der User einen pre_sponsor - schon inaktiv
|
||||
return self::findNextActiveSponsor($user->pre_sponsor);
|
||||
}
|
||||
//dump('not sponsor');
|
||||
return $user;
|
||||
}
|
||||
|
||||
public static function deactiveUser($user){
|
||||
|
||||
$user->pre_sponsor = $user->m_sponsor; //den sponsor speichern für wiederherstellung
|
||||
$user->m_sponsor = null;
|
||||
$user->active = false;
|
||||
$user->save();
|
||||
}
|
||||
|
||||
public static function reactiveUser($user){
|
||||
|
||||
if($user->pre_sponsor){
|
||||
$pre_sponsor = self::findNextActiveSponsor($user->pre_sponsor);
|
||||
$user->m_sponsor = $pre_sponsor->id; //den sponsor wiederherstellen
|
||||
$user->pre_sponsor = null;
|
||||
}
|
||||
$user->active = true;
|
||||
$user->save();
|
||||
}
|
||||
|
||||
public static function deleteUser(User $user)
|
||||
{
|
||||
if($user->account){
|
||||
$user->account->delete();
|
||||
}
|
||||
if($user->shop){
|
||||
$subdomain_name = $user->shop->slug.'.mivita.care';
|
||||
$user->shop->name = "delete".$user->shop->id;
|
||||
$user->shop->slug = "delete".$user->shop->id;
|
||||
$user->shop->save();
|
||||
$user->shop->delete();
|
||||
//isset KAS - delete Subdomain
|
||||
if(!Util::isTestSystem()){
|
||||
$kas = new KasController();
|
||||
$pra = array(
|
||||
'subdomain_name' => $subdomain_name,
|
||||
);
|
||||
$kas->action('delete_subdomain', $pra);
|
||||
}
|
||||
}
|
||||
$user->email = "delete".time().mt_rand(1000000, 9999999);
|
||||
$user->password = "delete".time();
|
||||
$user->confirmed = 0;
|
||||
$user->confirmation_code = "delete".time();
|
||||
$user->confirmation_date = null;
|
||||
$user->confirmation_code_to = null;
|
||||
$user->confirmation_code_remider = 2;
|
||||
$user->agreement = null;
|
||||
$user->active = 0;
|
||||
$user->remember_token = '';
|
||||
$user->active_date = null;
|
||||
$user->admin = 0;
|
||||
$user->deleted_at = now();
|
||||
$user->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function reactiveUserResetChilds($user_id, $info = ''){
|
||||
|
||||
$user = User::find($user_id);
|
||||
if(!$user){
|
||||
\Log::channel('cleanup')->error('reactiveUserResetChilds find no user by user_id:'.$user_id);
|
||||
return 0;
|
||||
}
|
||||
$data = [
|
||||
'user_id' => $user->id,
|
||||
'email' => $user->email,
|
||||
'm_account' => $user->account ? $user->account->m_account : '',
|
||||
'm_first_name' => $user->account ? $user->account->m_first_name : '',
|
||||
'm_last_name' => $user->account ? $user->account->m_last_name : '',
|
||||
];
|
||||
\Log::channel('cleanup')->info('reactiveUserResetChilds '.$info.' : '.json_encode($data));
|
||||
|
||||
self::reactiveUser($user);
|
||||
self::resetChildsToSponsor($user->id);
|
||||
}
|
||||
|
||||
public static function deactiveUserNewSponsorChilds($user_id, $info = ''){
|
||||
|
||||
$user = User::find($user_id);
|
||||
if(!$user){
|
||||
\Log::channel('cleanup')->error('deactiveUserNewSponsorChilds find no user by user_id:'.$user_id);
|
||||
return 0;
|
||||
}
|
||||
$data = [
|
||||
'user_id' => $user->id,
|
||||
'email' => $user->email,
|
||||
'm_account' => $user->account ? $user->account->m_account : '',
|
||||
'm_first_name' => $user->account ? $user->account->m_first_name : '',
|
||||
'm_last_name' => $user->account ? $user->account->m_last_name : '',
|
||||
];
|
||||
|
||||
$active_sponsor = self::findNextActiveSponsor($user->m_sponsor);
|
||||
if($active_sponsor){
|
||||
self::setNewSponsorToChilds($user->id, $active_sponsor->id);
|
||||
}else{
|
||||
\Log::channel('cleanup')->error('cleanUpInActiveUser find no active_sponsor by inactive_user:'.$user->id);
|
||||
}
|
||||
\Log::channel('cleanup')->info('deactiveUserNewSponsorChilds '.$info.' : '.json_encode($data));
|
||||
self::deactiveUser($user);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -270,12 +270,28 @@ class Util
|
|||
return \Config::get('app.url') === config('app.domain').config('app.tld_shop');
|
||||
}
|
||||
|
||||
public static function isTestSystem(){
|
||||
public static function isTestSystem($dev = false){
|
||||
if(\Config::get('app.tld_care') === '.test' || \Config::get('app.tld_shop') === '.lshop'){
|
||||
if($dev && config('app.debug') !== true){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function formatBytes($size, $precision = 2)
|
||||
{
|
||||
if ($size > 0) {
|
||||
$size = (int) $size;
|
||||
$base = log($size) / log(1024);
|
||||
$suffixes = array(' bytes', ' KB', ' MB', ' GB', ' TB');
|
||||
|
||||
return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
|
||||
} else {
|
||||
return $size;
|
||||
}
|
||||
}
|
||||
|
||||
public static function sanitize($string, $force_lowercase = true, $anal = false, $substr = false)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use App\Services\Shop;
|
||||
use App\Models\Country;
|
||||
use App\Models\Product;
|
||||
use App\Models\ShippingCountry;
|
||||
|
|
@ -136,6 +137,12 @@ class Yard extends Cart
|
|||
}
|
||||
|
||||
|
||||
public function getShippingPrice()
|
||||
{
|
||||
return $this->shipping_price;
|
||||
}
|
||||
|
||||
|
||||
public function getYContent()
|
||||
{
|
||||
if (is_null($this->ysession->get($this->yinstance))) {
|
||||
|
|
@ -149,7 +156,7 @@ class Yard extends Cart
|
|||
$this->calculateShippingPrice();
|
||||
}
|
||||
|
||||
public function setShippingCountryWithPrice($shipping_country_id, $shipping_is_for = 'ot')
|
||||
public function setShippingCountryWithPrice($shipping_country_id, $shipping_is_for = 'ot-member')
|
||||
{
|
||||
$this->shipping_country_id = $shipping_country_id;
|
||||
$this->putYardExtra('shipping_country_id', $shipping_country_id);
|
||||
|
|
@ -208,6 +215,15 @@ class Yard extends Cart
|
|||
return $this->shipping_free;
|
||||
}
|
||||
|
||||
public function getShippingFreeMissingValue()
|
||||
{
|
||||
if($this->shipping_free && $this->total(2, '.', '') < $this->shipping_free){
|
||||
return $this->shipping_free - $this->total(2, '.', '');
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
private function calculateShippingPrice(){
|
||||
|
||||
$shippingCountry = ShippingCountry::find($this->shipping_country_id);
|
||||
|
|
@ -246,8 +262,8 @@ class Yard extends Cart
|
|||
}
|
||||
if($shipping_price){
|
||||
$price = $shipping_price->price;
|
||||
$this->num_comp = 0;
|
||||
if($this->shipping_is_for === 'me'){
|
||||
$this->num_comp = 0; //compensation is checked in Settings
|
||||
if(Shop::isCompProducts($this->shipping_is_for)){
|
||||
$price = $shipping_price->price_comp;
|
||||
$this->num_comp = $shipping_price->num_comp;
|
||||
|
||||
|
|
|
|||
94
app/Services/dbip/MyDBIP.php
Normal file
94
app/Services/dbip/MyDBIP.php
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com database query and management class
|
||||
*
|
||||
* Copyright (C) 2022 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
namespace App\Services\dbip;
|
||||
|
||||
use PDO;
|
||||
use Exception;
|
||||
use PDOException;
|
||||
use App\Models\DbipLookup;
|
||||
use App\Models\DbipLookup2;
|
||||
use App\Models\DbipLookup3;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
|
||||
class DBIPException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
class MyDBIP {
|
||||
|
||||
const VERSION = 4;
|
||||
|
||||
|
||||
static public function lookup($addr) {
|
||||
if ($ret = self::doLookup(self::addrType($addr), inet_pton($addr))) {
|
||||
return $ret;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static public function doLookup($addrType, $addrStart) {
|
||||
|
||||
$res = DbipLookup::where('addr_type', $addrType)->where('ip_start', '<=', $addrStart)->orderBy('ip_start', 'desc')->first();
|
||||
$c1 = isset($res->country) ? $res->country : null;
|
||||
|
||||
$res = DbipLookup2::where('addr_type', $addrType)->where('ip_start', '<=', $addrStart)->orderBy('ip_start', 'desc')->first();
|
||||
$c2 = isset($res->country) ? $res->country : null;
|
||||
|
||||
if($c1 == $c2){
|
||||
return $c1;
|
||||
}
|
||||
|
||||
$res = DbipLookup3::where('addr_type', $addrType)->where('ip_start', '<=', $addrStart)->orderBy('ip_start', 'desc')->first();
|
||||
if(isset($res->country)){
|
||||
return $res->country;
|
||||
}
|
||||
|
||||
//look in api
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static private function addrType($addr) {
|
||||
if (ip2long($addr) !== false) {
|
||||
return "ipv4";
|
||||
} else if (preg_match('/^[0-9a-fA-F:]+$/', $addr) && @inet_pton($addr)) {
|
||||
return "ipv6";
|
||||
}
|
||||
throw new DBIPException("unknown address type for {$addr}");
|
||||
}
|
||||
|
||||
static public function insert($addr, $country) {
|
||||
|
||||
$lookup = new DbipLookup3();
|
||||
$lookup->addr_type = self::addrType($addr);
|
||||
$lookup->ip_start = inet_pton($addr);
|
||||
$lookup->ip_end = inet_pton($addr);
|
||||
$lookup->country = strtoupper($country);
|
||||
$lookup->save();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
211
app/Services/dbip/dbip-convert.php
Executable file
211
app/Services/dbip/dbip-convert.php
Executable file
|
|
@ -0,0 +1,211 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com CSV database format conversion tool
|
||||
*
|
||||
* Copyright (C) 2020 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
$outputFormats = [
|
||||
"range" => function(array $csvData, $of, string $firstIpBin, string $lastIpBin): void {
|
||||
writeCSV($of, $csvData);
|
||||
},
|
||||
"cidr" => function(array $csvData, $of, string $firstIpBin, string $lastIpBin): void {
|
||||
array_shift($csvData);
|
||||
foreach (rangeToCIDR($firstIpBin, $lastIpBin) as $cidrNet) {
|
||||
$csvData[0] = $cidrNet;
|
||||
writeCSV($of, $csvData);
|
||||
}
|
||||
},
|
||||
"long" => function(array $csvData, $of, string $firstIpBin, string $lastIpBin): void {
|
||||
if (($firstIpLong = ip2long($csvData[0])) === false) {
|
||||
throw new Exception("invalid IP address for long conversion : {$csvData[0]}");
|
||||
} else if (($lastIpLong = ip2long($csvData[1])) === false) {
|
||||
throw new Exception("invalid IP address for long conversion : {$csvData[1]}");
|
||||
}
|
||||
$csvData[0] = $firstIpLong;
|
||||
$csvData[1] = $lastIpLong;
|
||||
writeCSV($of, $csvData);
|
||||
},
|
||||
];
|
||||
|
||||
function writeCSV($of, $csvData) {
|
||||
fputcsv($of, $csvData);
|
||||
}
|
||||
|
||||
function vEcho(string $s): void {
|
||||
if (!$GLOBALS["verbose"]) {
|
||||
return;
|
||||
}
|
||||
echo $s;
|
||||
}
|
||||
|
||||
function findLargestNetwork(string $ipStartBin): int {
|
||||
for ($i = strlen($ipStartBin); $i--; $i >= 0) {
|
||||
$byte = ord($ipStartBin[$i]);
|
||||
for ($j = 7; $j >= 0; $j--) {
|
||||
if ($byte & (0xff >> $j)) {
|
||||
return ($i << 3) + $j + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function getLastAddress(string $ipStartBin, int $cidrBits): string {
|
||||
$ret = $ipStartBin;
|
||||
for ($i = strlen($ipStartBin); $i--; $i >= 0) {
|
||||
$firstBit = ($i << 3) + 1;
|
||||
$lastBit = ($i + 1) << 3;
|
||||
if ($cidrBits > $lastBit) {
|
||||
continue;
|
||||
} else if ($cidrBits < $firstBit) {
|
||||
$ret[$i] = "\xff";
|
||||
} else {
|
||||
$ret[$i] = chr(ord($ret[$i]) | (0xff >> ($cidrBits - $firstBit + 1)));
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function getNextAddress(string $ipStartBin): string {
|
||||
$ret = $ipStartBin;
|
||||
for ($i = strlen($ipStartBin); $i--; $i >= 0) {
|
||||
for ($j = 7; $j >= 0; $j--) {
|
||||
$byte = ord($ret[$i]);
|
||||
$mask = 1 << (7 - $j);
|
||||
if ($byte & $mask) {
|
||||
$ret[$i] = chr($byte & ~$mask);
|
||||
} else {
|
||||
$ret[$i] = chr($byte | $mask);
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Exception("no next address for " . inet_ntop($ipStartBin));
|
||||
}
|
||||
|
||||
function rangeToCIDR(string $ipStartBin, string $ipEndBin): array {
|
||||
if (strcmp($ipStartBin, $ipEndBin) > 0) {
|
||||
throw new Exception("wrong ip address order");
|
||||
}
|
||||
$cidrNets = [];
|
||||
$cidrBits = findLargestNetwork($ipStartBin);
|
||||
do {
|
||||
$lastAddrBin = getLastAddress($ipStartBin, $cidrBits);
|
||||
if (($cmp = strcmp($lastAddrBin, $ipEndBin)) <= 0) {
|
||||
$cidrNets[] = inet_ntop($ipStartBin) . "/" . $cidrBits;
|
||||
if ($cmp === 0) {
|
||||
return $cidrNets;
|
||||
}
|
||||
$ipStartBin = getNextAddress($lastAddrBin);
|
||||
$cidrBits = findLargestNetwork($ipStartBin);
|
||||
} else {
|
||||
$cidrBits++;
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$exitCode = 0;
|
||||
$opts = getopt("i:o:f:qhw46");
|
||||
$verbose = !isset($opts["q"]);
|
||||
|
||||
if (!$opts || isset($opts["h"]) || !isset($opts["i"]) || !isset($opts["o"]) || !isset($opts["f"]) || (isset($opts["4"]) && isset($opts["6"]))) {
|
||||
echo "usage: {$argv[0]} -i <inputFileName.csv> -o <outputFileName.csv> -f <outputFormat> [-4|-6] [-w] [-q]\n";
|
||||
echo " -i input CSV file\n";
|
||||
echo " -o output file name\n";
|
||||
echo " -f output format (" . implode("|", array_keys($outputFormats)) . ")\n";
|
||||
echo " -4 output ipv4 networks only\n";
|
||||
echo " -6 output ipv6 networks only\n";
|
||||
echo " -w overwrite output file if it already exists\n";
|
||||
echo " -q be quiet\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$inputFile = $opts["i"];
|
||||
if (!file_exists($inputFile)) {
|
||||
throw new Exception("cannot find input file: {$inputFile}");
|
||||
} else if (!is_readable($inputFile)) {
|
||||
throw new Exception("cannot read input file: {$inputFile}");
|
||||
}
|
||||
if (substr($inputFile, -3) === ".gz") {
|
||||
$inputFile = "compress.zlib://" . $inputFile;
|
||||
}
|
||||
if (!$if = fopen($inputFile, "r")) {
|
||||
throw new Exception("cannot open input file: {$inputFile}");
|
||||
}
|
||||
|
||||
$outputFile = $opts["o"];
|
||||
if (file_exists($outputFile) && !isset($opts["w"])) {
|
||||
throw new Exception("output file {$outputFile} already exists, use -w to force overwrite");
|
||||
}
|
||||
if (substr($outputFile, -3) === ".gz") {
|
||||
$outputFile = "compress.zlib://" . $outputFile;
|
||||
}
|
||||
if (!$of = fopen($outputFile, "w")) {
|
||||
throw new Exception("cannot open output file: {$outPutFile}");
|
||||
}
|
||||
|
||||
if (!isset($outputFormats[$opts["f"]])) {
|
||||
throw new Exception("invalid output format {$opts['f']}");
|
||||
}
|
||||
$outputFormatter = $outputFormats[$opts["f"]];
|
||||
|
||||
$i = 0;
|
||||
while ($r = fgetcsv($if, 8192)) {
|
||||
$i++;
|
||||
[ $firstIp, $lastIp ] = $r;
|
||||
try {
|
||||
if (!$firstIpBin = inet_pton($firstIp)) {
|
||||
throw new Exception("invalid first IP '{$firstIp}' in CSV record");
|
||||
} else if (!$lastIpBin = inet_pton($lastIp)) {
|
||||
throw new Exception("invalid last IP '{$lastIp}' in CSV record");
|
||||
} else if (($addrLen = strlen($firstIpBin)) !== strlen($lastIpBin)) {
|
||||
throw new Exception("first and last IP address family mismatch ({$firstIp} / {$lastIp})");
|
||||
}
|
||||
if (isset($opts["4"]) && ($addrLen !== 4)) {
|
||||
continue;
|
||||
} else if (isset($opts["6"]) && ($addrLen !== 16)) {
|
||||
continue;
|
||||
}
|
||||
$outputFormatter($r, $of, $firstIpBin, $lastIpBin);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("line {$i}: {$e->getMessage()}");
|
||||
}
|
||||
}
|
||||
fclose($if);
|
||||
fclose($of);
|
||||
|
||||
vEcho("Wrote {$outputFile}\n");
|
||||
|
||||
} catch (Exception $e) {
|
||||
if ($stdErr = @fopen("php://stderr", "w")) {
|
||||
fwrite($stdErr, "ERROR: {$e->getMessage()}\n");
|
||||
fclose($stdErr);
|
||||
} else {
|
||||
echo "ERROR: {$e->getMessage()}\n";
|
||||
}
|
||||
$exitCode = 1;
|
||||
}
|
||||
if ($exitCode) {
|
||||
exit($exitCode);
|
||||
}
|
||||
12
app/Services/dbip/dbip-country-ipinfo-2024-test.csv
Normal file
12
app/Services/dbip/dbip-country-ipinfo-2024-test.csv
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
1.0.0.0,1.0.0.254,AU,Australia,OC,Oceania
|
||||
1.0.0.255,1.0.0.255,ID,Indonesia,AS,Asia
|
||||
1.0.1.0,1.0.3.255,CN,China,AS,Asia
|
||||
1.0.4.0,1.0.7.255,AU,Australia,OC,Oceania
|
||||
1.0.8.0,1.0.15.255,CN,China,AS,Asia
|
||||
1.0.16.0,1.0.31.255,JP,Japan,AS,Asia
|
||||
1.0.32.0,1.0.63.255,CN,China,AS,Asia
|
||||
1.0.64.0,1.0.127.255,JP,Japan,AS,Asia
|
||||
1.0.128.0,1.0.218.40,TH,Thailand,AS,Asia
|
||||
1.0.218.41,1.0.218.41,MY,Malaysia,AS,Asia
|
||||
1.0.218.42,1.0.255.255,TH,Thailand,AS,Asia
|
||||
1.1.0.0,1.1.0.255,CN,China,AS,Asia
|
||||
|
1980348
app/Services/dbip/dbip-country-ipinfo-2024.csv
Normal file
1980348
app/Services/dbip/dbip-country-ipinfo-2024.csv
Normal file
File diff suppressed because it is too large
Load diff
586697
app/Services/dbip/dbip-country-lite-2024-07.csv
Normal file
586697
app/Services/dbip/dbip-country-lite-2024-07.csv
Normal file
File diff suppressed because it is too large
Load diff
10
app/Services/dbip/dbip-update.ini.sample
Normal file
10
app/Services/dbip/dbip-update.ini.sample
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[account]
|
||||
; Your account key is available in your customer section at https://db-ip.com/account/
|
||||
accountKey = INSERT_YOUR_ACCOUNT_KEY_HERE
|
||||
|
||||
[database]
|
||||
; This is the PDO Data Source Name for your database instance, see http://php.net/manual/pdo.construct.php
|
||||
dataSourceName = "mysql:host=localhost;dbname=myapp"
|
||||
; dbUser and dbPassword are the database account credentials
|
||||
dbUser = myapp
|
||||
dbPassword = myapp123
|
||||
327
app/Services/dbip/dbip-update.php
Executable file
327
app/Services/dbip/dbip-update.php
Executable file
|
|
@ -0,0 +1,327 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com database update tool
|
||||
*
|
||||
* Copyright (C) 2021 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
require "dbip.class.php";
|
||||
|
||||
const API_BASE = "https://db-ip.com/account";
|
||||
const DEFAULT_CONF = "dbip-update.ini";
|
||||
|
||||
function apiRequest($path, $key) {
|
||||
$url = API_BASE . "/" . $key . "/db" . $path;
|
||||
if (($jsonData = file_get_contents($url)) === false) {
|
||||
throw new Exception("cannot fetch API result from {$url}");
|
||||
} else if (!isset($jsonData) || !$jsonData || (($resp = json_decode($jsonData)) === false)) {
|
||||
throw new Exception("cannot decode API result from {$url}");
|
||||
} else if (isset($resp->error)) {
|
||||
throw new Exception("API error: {$resp->error}");
|
||||
}
|
||||
return $resp;
|
||||
}
|
||||
|
||||
function vEcho($s) {
|
||||
if (!$GLOBALS["verbose"]) {
|
||||
return false;
|
||||
}
|
||||
echo $s;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$exitCode = 0;
|
||||
$opts = getopt("k:d:f:o:zZqlnwb:u:p:t:c:D");
|
||||
$verbose = !isset($opts["q"]);
|
||||
|
||||
if (isset($opts["c"])) {
|
||||
if (!file_exists($opts["c"]) || !is_readable($opts["c"])) {
|
||||
throw new Exception("cannot read configuration file {$opts['c']}");
|
||||
}
|
||||
$confName = $opts["c"];
|
||||
} else if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . DEFAULT_CONF) && is_readable(__DIR__ . DIRECTORY_SEPARATOR . DEFAULT_CONF)) {
|
||||
$confName = __DIR__ . DIRECTORY_SEPARATOR . DEFAULT_CONF;
|
||||
}
|
||||
|
||||
if (isset($confName)) {
|
||||
if (($conf = parse_ini_file($confName)) === false) {
|
||||
throw new Exception("cannot parse configuration file {$confName}");
|
||||
}
|
||||
$confMap = [
|
||||
"accountKey" => "k",
|
||||
"dbType" => "d",
|
||||
"format" => "f",
|
||||
"outputDir" => "o",
|
||||
"outputFileName" => "o",
|
||||
"dataSourceName" => "b",
|
||||
"dbUser" => "u",
|
||||
"dbPassword" => "p",
|
||||
"dbTableName" => "t",
|
||||
];
|
||||
foreach ($conf as $name => $value) {
|
||||
if (!isset($confMap[$name])) {
|
||||
throw new Exception("invalid configuration parameter {$name}");
|
||||
} else if (!isset($opts[$confMap[$name]])) {
|
||||
$opts[$confMap[$name]] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($opts["k"]) || !$opts["k"]) {
|
||||
echo "usage: {$argv[0]} -k <accountKey> [-l] [-d <dbType>] [-f <format>] [-o <outputDir|outputFileName>] [-b <dataSourceName> [-u <dbUser>] [-p <dbPassword] [-t <dbTableName>] [-D]] [-c <configFile>] [-n] [-z|-Z] [-w] [-q]\n";
|
||||
echo " -l list available items and exit\n";
|
||||
echo " -n request new items only\n";
|
||||
echo " -z fetch uncompressed file (default for mmdb format)\n";
|
||||
echo " -Z fetch compressed file (default for csv format)\n";
|
||||
echo " -w overwrite destination file if it already exists\n";
|
||||
echo " -b PDO DSN for database update (ie. \"mysql:host=localhost;dbname=dbip\")\n";
|
||||
echo " -u database username (default 'root')\n";
|
||||
echo " -p database password (default '')\n";
|
||||
echo " -t name of database table (default 'dbip_lookup')\n";
|
||||
echo " -D do not use a temporary table (table specified by -t must be empty)\n";
|
||||
echo " -q be quiet\n";
|
||||
exit(1);
|
||||
}
|
||||
$apiKey = $opts["k"];
|
||||
|
||||
if (!isset($opts["d"])) {
|
||||
$dbList = apiRequest("/", $apiKey);
|
||||
if (count((array)$dbList) > 1) {
|
||||
vEcho("Use -d to select a database type :\n");
|
||||
foreach ($dbList as $dbType => $dbInfo) {
|
||||
echo $dbType . "\n";
|
||||
}
|
||||
exit();
|
||||
} else {
|
||||
foreach ($dbList as $dbType => $dbInfo) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$dbType = $opts["d"];
|
||||
}
|
||||
|
||||
if (isset($opts["b"])) {
|
||||
if (isset($opts["o"])) {
|
||||
throw new Exception("Arguments -b and -o cannot be used in the same command line");
|
||||
}
|
||||
$dbUser = isset($opts["u"]) ? $opts["u"] : "root";
|
||||
$dbPassword = isset($opts["p"]) ? $opts["p"] : "";
|
||||
$dbTable = isset($opts["t"]) ? $opts["t"] : "dbip_lookup";
|
||||
$format = "csv";
|
||||
try {
|
||||
$dsn = $opts["b"];
|
||||
if (preg_match('/^mysql:/', $dsn)) {
|
||||
if (!preg_match('/charset=/', $dsn)) {
|
||||
$dsn .= ";charset=utf8mb4";
|
||||
}
|
||||
$dbQuoteChar = '`'; // backquote for MySQL
|
||||
} else {
|
||||
$dbQuoteChar = '"'; // double quote for ANSI SQL
|
||||
}
|
||||
$db = new PDO($dsn, $dbUser, $dbPassword);
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
||||
$dbUseTempTable = !isset($opts["D"]);
|
||||
} catch (PDOException $e) {
|
||||
throw new Exception("Cannot connect to database: {$e->getMessage()}");
|
||||
}
|
||||
} else {
|
||||
if (!isset($opts["f"])) {
|
||||
$filesList = apiRequest("/{$dbType}", $apiKey);
|
||||
vEcho("Use -f to specify a format for your {$dbType} subscription :\n");
|
||||
foreach ($filesList as $format => $fileInfo) {
|
||||
echo $format . "\n";
|
||||
}
|
||||
exit();
|
||||
}
|
||||
$format = $opts["f"];
|
||||
}
|
||||
$onlyNew = isset($opts["n"]);
|
||||
|
||||
try {
|
||||
$queryString = $onlyNew ? "?new=1" : "";
|
||||
$fileInfo = apiRequest("/{$dbType}/{$format}{$queryString}", $apiKey);
|
||||
if ($onlyNew && !$fileInfo) {
|
||||
vEcho("there are no new downloads available\n");
|
||||
exit(0);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("cannot access download info : {$e->getMessage()}");
|
||||
}
|
||||
|
||||
if (isset($opts["l"])) {
|
||||
if (!isset($fileInfo)) {
|
||||
vEcho("no download file match\n");
|
||||
exit();
|
||||
}
|
||||
foreach ($fileInfo as $name => $value) {
|
||||
echo "{$name}: {$value}\n";
|
||||
}
|
||||
exit();
|
||||
}
|
||||
|
||||
if (isset($opts["z"])) {
|
||||
$uncompress = true;
|
||||
} else if (isset($opts["Z"]) || ($format === "csv")) {
|
||||
$uncompress = false;
|
||||
} else {
|
||||
$uncompress = true;
|
||||
}
|
||||
|
||||
$outputFile = "." . DIRECTORY_SEPARATOR . $fileInfo->name;
|
||||
if (isset($opts["o"])) {
|
||||
if (is_dir($opts["o"])) {
|
||||
$outputFile = $opts["o"] . DIRECTORY_SEPARATOR . $fileInfo->name;
|
||||
} else {
|
||||
$outputFile = $opts["o"];
|
||||
}
|
||||
}
|
||||
$sourcePrefix = $uncompress ? "compress.zlib://" : "";
|
||||
if ($uncompress && preg_match('/\.gz$/i', $outputFile)) {
|
||||
$outputFile = preg_replace('/\.gz$/i', '', $outputFile);
|
||||
}
|
||||
$outputTempFile = $outputFile . ".update-tmp";
|
||||
|
||||
if (file_exists($outputTempFile) && !unlink($outputTempFile)) {
|
||||
throw new Exception("cannot delete temporary file {$outputTempFile}");
|
||||
} else if (!isset($db) && file_exists($outputFile) && !isset($opts["w"])) {
|
||||
throw new Exception("destination file {$outputFile} already exists, use -w to force overwrite");
|
||||
}
|
||||
|
||||
vEcho("Starting update for {$dbType} ({$fileInfo->date})\n");
|
||||
if (!copy($sourcePrefix . $fileInfo->url, $outputTempFile, stream_context_create([], [ "notification" => function($notificationCode, $severity, $message, $messageCode, $bytesTransferred, $bytesMax) {
|
||||
static $totBytes, $prevPct = false;
|
||||
if ($bytesMax) {
|
||||
$totBytes = $bytesMax;
|
||||
}
|
||||
if ($bytesTransferred) {
|
||||
if (isset($totBytes) && $totBytes) {
|
||||
$pct = number_format(($bytesTransferred / $totBytes) * 100, 1);
|
||||
}
|
||||
if ($pct !== $prevPct) {
|
||||
vEcho("\rDownloading: " . number_format($bytesTransferred / 1024) . " KB" . (isset($pct) ? " ({$pct}%)" : ""));
|
||||
$prevPct = $pct;
|
||||
}
|
||||
}
|
||||
}]))) {
|
||||
throw new Exception("unable to download file to {$outputTempFile}");
|
||||
}
|
||||
vEcho("\rDownload completed: " . number_format(filesize($outputTempFile) / 1024, 1) . " KB\n");
|
||||
|
||||
$checkPrefix = $uncompress ? "" : "compress.zlib://";
|
||||
if (isset($fileInfo->md5sum) || isset($fileInfo->sha1sum)) {
|
||||
vEcho("Verify signature: ");
|
||||
if (isset($fileInfo->md5sum)) {
|
||||
$md5sum = md5_file($checkPrefix . $outputTempFile);
|
||||
if ($md5sum !== $fileInfo->md5sum) {
|
||||
vEcho("MISMATCH {$md5sum} != {$fileInfo->md5sum}\n");
|
||||
throw new Exception("MD5 signature verification failed, file is probably corrupt or altered");
|
||||
}
|
||||
vEcho("[MD5] ");
|
||||
}
|
||||
if (isset($fileInfo->sha1sum)) {
|
||||
$sha1sum = sha1_file($checkPrefix . $outputTempFile);
|
||||
if ($sha1sum !== $fileInfo->sha1sum) {
|
||||
vEcho("MISMATCH {$sha1sum} != {$fileInfo->sha1sum}\n");
|
||||
throw new Exception("SHA1 signature verification failed, file is probably corrupt or altered");
|
||||
}
|
||||
vEcho("[SHA1] ");
|
||||
}
|
||||
vEcho("passed\n");
|
||||
}
|
||||
|
||||
if (isset($db)) {
|
||||
$dbip = new DBIP($db, $dbQuoteChar);
|
||||
$relId = $dbType;
|
||||
if ($fileInfo->version) {
|
||||
$relId .= "-v{$fileInfo->version}";
|
||||
}
|
||||
switch ($relId) {
|
||||
case "ip-to-country-lite": $importType = DBIP::TYPE_COUNTRY_LITE; break;
|
||||
case "ip-to-city-lite": $importType = DBIP::TYPE_CITY_LITE; break;
|
||||
case "ip-to-country-v4": $importType = DBIP::TYPE_COUNTRY_V4; break;
|
||||
case "ip-to-location-v4": $importType = DBIP::TYPE_LOCATION_V4; break;
|
||||
case "ip-to-isp-v4": $importType = DBIP::TYPE_ISP_V4; break;
|
||||
case "ip-to-location-isp-v4":
|
||||
case "ip-to-full-v4": $importType = DBIP::TYPE_FULL_V4; break;
|
||||
case "ip-to-country-v3": $importType = DBIP::TYPE_COUNTRY_V3; break;
|
||||
case "ip-to-location-v3": $importType = DBIP::TYPE_LOCATION_V3; break;
|
||||
case "ip-to-isp-v3": $importType = DBIP::TYPE_ISP_V3; break;
|
||||
case "ip-to-location-isp-v3":
|
||||
case "ip-to-full-v3": $importType = DBIP::TYPE_FULL_V3; break;
|
||||
case "ip-to-location-v2": $importType = DBIP::TYPE_LOCATION_V2; break;
|
||||
case "ip-to-isp-v2": $importType = DBIP::TYPE_ISP_V2; break;
|
||||
case "ip-to-location-isp-v2":
|
||||
case "ip-to-full-v2": $importType = DBIP::TYPE_FULL_V2; break;
|
||||
default: throw new Exception("unsupported database type");
|
||||
}
|
||||
if ($dbUseTempTable) {
|
||||
$tempTable = "dbip_update_" . time();
|
||||
$db->exec("drop table if exists {$dbQuoteChar}{$tempTable}{$dbQuoteChar}");
|
||||
$db->exec("create table {$dbQuoteChar}{$tempTable}{$dbQuoteChar} like {$dbQuoteChar}{$dbTable}{$dbQuoteChar}");
|
||||
} else {
|
||||
$tempTable = $dbTable;
|
||||
}
|
||||
$dbip->importFromCsv($outputTempFile, $importType, $tempTable, function($numRows) use ($fileInfo) {
|
||||
if ($numRows % 1000) {
|
||||
return false;
|
||||
}
|
||||
if (isset($fileInfo->rows) && $fileInfo->rows) {
|
||||
$pct = number_format(($numRows / $fileInfo->rows) * 100, 1);
|
||||
}
|
||||
vEcho("\rImporting: " . number_format($numRows) . " rows" . (isset($pct) ? " ({$pct}%)" : ""));
|
||||
});
|
||||
$numRows = (int)$db->query("select count(1) cnt from {$dbQuoteChar}{$tempTable}{$dbQuoteChar}")->fetchObject()->cnt;
|
||||
if ($dbUseTempTable) {
|
||||
$db->exec("drop table if exists {$dbQuoteChar}{$tempTable}_old{$dbQuoteChar}");
|
||||
$db->exec("rename table {$dbQuoteChar}{$dbTable}{$dbQuoteChar} to {$dbQuoteChar}{$tempTable}_old{$dbQuoteChar}, {$dbQuoteChar}{$tempTable}{$dbQuoteChar} to {$dbQuoteChar}{$dbTable}{$dbQuoteChar}");
|
||||
$db->exec("drop table {$dbQuoteChar}{$tempTable}_old{$dbQuoteChar}");
|
||||
}
|
||||
vEcho("\rDatabase updated: " . number_format($numRows) . " rows imported\n");
|
||||
} else {
|
||||
if (!rename($outputTempFile, $outputFile)) {
|
||||
throw new Exception("cannot rename temporary file {$outputTempFile} to {$outputFile}");
|
||||
}
|
||||
vEcho("Wrote {$outputFile}\n");
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
if ($stdErr = @fopen("php://stderr", "w")) {
|
||||
fwrite($stdErr, "ERROR: {$e->getMessage()}\n");
|
||||
fclose($stdErr);
|
||||
} else {
|
||||
echo "ERROR: {$e->getMessage()}\n";
|
||||
}
|
||||
$exitCode = 1;
|
||||
} finally {
|
||||
if (isset($outputTempFile) && file_exists($outputTempFile)) {
|
||||
unlink($outputTempFile);
|
||||
}
|
||||
if (isset($db) && isset($tempTable) && $dbUseTempTable) {
|
||||
$db->exec("drop table if exists {$dbQuoteChar}{$tempTable}{$dbQuoteChar}");
|
||||
$db->exec("drop table if exists {$dbQuoteChar}{$tempTable}_old{$dbQuoteChar}");
|
||||
}
|
||||
}
|
||||
if ($exitCode) {
|
||||
exit($exitCode);
|
||||
}
|
||||
346
app/Services/dbip/dbip.class.php
Executable file
346
app/Services/dbip/dbip.class.php
Executable file
|
|
@ -0,0 +1,346 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com database query and management class
|
||||
*
|
||||
* Copyright (C) 2022 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
use PDO;
|
||||
use Exception;
|
||||
use PDOException;
|
||||
|
||||
|
||||
class DBIPException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
class DBIP {
|
||||
|
||||
const VERSION = 4;
|
||||
|
||||
const TYPE_COUNTRY_LITE = 1;
|
||||
const TYPE_CITY_LITE = 2;
|
||||
const TYPE_COUNTRY_V4 = 3;
|
||||
const TYPE_LOCATION_V4 = 4;
|
||||
const TYPE_ISP_V4 = 5;
|
||||
const TYPE_FULL_V4 = 6;
|
||||
|
||||
const TYPE_COUNTRY_V3 = 7;
|
||||
const TYPE_LOCATION_V3 = 8;
|
||||
const TYPE_ISP_V3 = 9;
|
||||
const TYPE_FULL_V3 = 10;
|
||||
|
||||
const TYPE_LOCATION_V2 = 11;
|
||||
const TYPE_ISP_V2 = 12;
|
||||
const TYPE_FULL_V2 = 13;
|
||||
|
||||
const TYPE_COUNTRY_IPINFO = 15;
|
||||
|
||||
const TYPE_COUNTRY = self::TYPE_COUNTRY_V4;
|
||||
const TYPE_LOCATION = self::TYPE_LOCATION_V4;
|
||||
const TYPE_ISP = self::TYPE_ISP_V4;
|
||||
const TYPE_FULL = self::TYPE_FULL_V4;
|
||||
|
||||
private $db;
|
||||
protected $dbQuoteChar = "";
|
||||
|
||||
public function __construct(PDO $db, $dbQuoteChar = "") {
|
||||
$this->db = $db;
|
||||
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$this->dbQuoteChar = $dbQuoteChar;
|
||||
}
|
||||
|
||||
public function importFromCsv($fileName, $type, $tableName = "dbip_lookup", $progressCallback = null) {
|
||||
switch ($type) {
|
||||
case self::TYPE_COUNTRY_LITE:
|
||||
$fields = array("ip_start", "ip_end", "country");
|
||||
$fieldsprepare = $fields;
|
||||
break;
|
||||
case self::TYPE_COUNTRY_IPINFO:
|
||||
$fields = array("ip_start", "ip_end", "country", "d1", "d2", "d3");
|
||||
$fieldsprepare = array("ip_start", "ip_end", "country");
|
||||
break;
|
||||
case self::TYPE_CITY_LITE:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "stateprov", "city", "latitude", "longitude");
|
||||
break;
|
||||
case self::TYPE_COUNTRY_V4:
|
||||
case self::TYPE_COUNTRY_V3:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country");
|
||||
break;
|
||||
case self::TYPE_LOCATION_V4:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "stateprov_code", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name", "weather_code");
|
||||
break;
|
||||
case self::TYPE_ISP_V4:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "isp_name", "as_number", "usage_type", "connection_type", "organization_name");
|
||||
break;
|
||||
case self::TYPE_FULL_V4:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "stateprov_code", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name", "weather_code", "isp_name", "as_number", "usage_type", "connection_type", "organization_name");
|
||||
break;
|
||||
case self::TYPE_LOCATION_V3:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name", "weather_code");
|
||||
break;
|
||||
case self::TYPE_ISP_V3:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "isp_name", "as_number", "connection_type", "organization_name");
|
||||
break;
|
||||
case self::TYPE_FULL_V3:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name", "weather_code", "isp_name", "as_number", "connection_type", "organization_name");
|
||||
break;
|
||||
case self::TYPE_LOCATION_V2:
|
||||
$fields = array("ip_start", "ip_end", "country", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name");
|
||||
break;
|
||||
case self::TYPE_ISP_V2:
|
||||
$fields = array("ip_start", "ip_end", "country", "isp_name", "connection_type", "organization_name");
|
||||
break;
|
||||
case self::TYPE_FULL_V2:
|
||||
$fields = array("ip_start", "ip_end", "country", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name", "isp_name", "connection_type", "organization_name");
|
||||
break;
|
||||
default:
|
||||
throw new DBIPException("invalid database type");
|
||||
}
|
||||
if (!file_exists($fileName)) {
|
||||
throw new DBIPException("file {$fileName} does not exists");
|
||||
}
|
||||
$q = $this->prepareImport($tableName, $fieldsprepare);
|
||||
if (preg_match('/\.gz(\..+)?$/', $fileName)) {
|
||||
$openName = "compress.zlib://" . $fileName;
|
||||
} else {
|
||||
$openName = $fileName;
|
||||
}
|
||||
$f = @fopen($openName, "r");
|
||||
if (!is_resource($f)) {
|
||||
throw new DBIPException("cannot open {$fileName} for reading");
|
||||
}
|
||||
$nrecs = 0;
|
||||
while ($r = fgetcsv($f, 1024, ",", '"', "\0")) {
|
||||
foreach ($r as $k => $v) {
|
||||
if (!isset($fields[$k])) {
|
||||
throw new DBIPException("invalid CSV record for {$r[0]}");
|
||||
}
|
||||
switch ($fields[$k]) {
|
||||
case "latitude":
|
||||
case "longitude":
|
||||
case "timezone_offset":
|
||||
$r[$k] = (float)$v;
|
||||
break;
|
||||
case "d1":
|
||||
case "d2":
|
||||
case "d3":
|
||||
unset($r[$k]);
|
||||
break;
|
||||
case "isp_name":
|
||||
case "organization_name":
|
||||
$r[$k] = mb_substr($v, 0, 128);
|
||||
break;
|
||||
case "city":
|
||||
case "district":
|
||||
case "stateprov":
|
||||
$r[$k] = mb_substr($v, 0, 80);
|
||||
break;
|
||||
case "zipcode":
|
||||
$r[$k] = mb_substr($v, 0, 20);
|
||||
break;
|
||||
case "timezone_name":
|
||||
$r[$k] = mb_substr($v, 0, 64);
|
||||
break;
|
||||
case "connection_type":
|
||||
case "stateprov_code":
|
||||
case "usage_type":
|
||||
case "geoname_id":
|
||||
case "as_number":
|
||||
if (!$r[$k]) $r[$k] = null;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
/*$r[] = self::addrType($r[0]);
|
||||
$r[0] = inet_pton($r[0]);
|
||||
$r[1] = inet_pton($r[1]);*/
|
||||
|
||||
$set = [
|
||||
0 => inet_pton($r[0]),
|
||||
1 => inet_pton($r[1]),
|
||||
2 => $r[2],
|
||||
3 => self::addrType($r[0])
|
||||
];
|
||||
$this->importRow($q, $set);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("cannot import record #{$nrecs}: {$e->getMessage()}");
|
||||
}
|
||||
if ((($nrecs % 100) === 0) && is_callable($progressCallback)) {
|
||||
call_user_func($progressCallback, $nrecs);
|
||||
}
|
||||
$nrecs++;
|
||||
}
|
||||
fclose($f);
|
||||
$this->finalizeImport();
|
||||
return $nrecs;
|
||||
}
|
||||
|
||||
public function lookup($addr, $tableName = "dbip_lookup") {
|
||||
if ($ret = $this->doLookup($tableName, self::addrType($addr), inet_pton($addr))) {
|
||||
$ret->ip_start = inet_ntop($ret->ip_start);
|
||||
$ret->ip_end = inet_ntop($ret->ip_end);
|
||||
return $ret;
|
||||
} else {
|
||||
throw new DBIPException("address not found");
|
||||
}
|
||||
}
|
||||
|
||||
protected function prepareImport($tableName, array $fields) {
|
||||
try {
|
||||
if ($this->db->query("select count(*) as cnt from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar}")->fetchObject()->cnt) {
|
||||
throw new DBIPException("table {$tableName} is not empty");
|
||||
}
|
||||
$this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
||||
$this->db->beginTransaction();
|
||||
$q = $this->db->prepare("insert into {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar} (" . implode(",", $fields) . ",addr_type) values (" . implode(",", array_fill(0, count($fields), "?")) . ",?)");
|
||||
return $q;
|
||||
} catch (PDOException $e) {
|
||||
throw new DBIPException("database error: {$e->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
protected function finalizeImport() {
|
||||
try{
|
||||
$this->db->commit();
|
||||
}catch (Exception $e) {
|
||||
throw new Exception("commit import record: {$e->getMessage()}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function importRow($res, $row) {
|
||||
return $res->execute($row);
|
||||
}
|
||||
|
||||
protected function doLookup($tableName, $addrType, $addrStart) {
|
||||
$q = $this->db->prepare("select * from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar} where addr_type = ? and ip_start <= ? order by ip_start desc limit 1");
|
||||
$q->execute(array($addrType, $addrStart));
|
||||
return $q->fetchObject();
|
||||
}
|
||||
|
||||
static private function addrType($addr) {
|
||||
if (ip2long($addr) !== false) {
|
||||
return "ipv4";
|
||||
} else if (preg_match('/^[0-9a-fA-F:]+$/', $addr) && @inet_pton($addr)) {
|
||||
return "ipv6";
|
||||
}
|
||||
throw new DBIPException("unknown address type for {$addr}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* DBIP MySQL class
|
||||
*
|
||||
* If you are using a MySQL database backend, please prefer the DBIP base class which uses the PDO mysql driver.
|
||||
* This is only meant to be used on PHP installations where PDO is disabled and the old mysql_* interface is available.
|
||||
*/
|
||||
class DBIPMySQL extends DBIP {
|
||||
|
||||
private $db;
|
||||
|
||||
public function __construct($db) {
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
protected function prepareImport($tableName, array $fields) {
|
||||
$q = mysql_query("select count(*) as cnt from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar}", $this->db);
|
||||
$r = mysql_fetch_object($q);
|
||||
mysql_free_result($q);
|
||||
if ($r->cnt) {
|
||||
throw new DBIPException("table {$tableName} is not empty");
|
||||
}
|
||||
return array($tableName, $fields);
|
||||
}
|
||||
|
||||
protected function finalizeImport() {
|
||||
}
|
||||
|
||||
protected function importRow($res, $row) {
|
||||
$vals = array();
|
||||
foreach ($row as $val) {
|
||||
$vals[] = "'" . mysql_real_escape_string($val) . "'";
|
||||
}
|
||||
if (!mysql_query("insert into {$this->dbQuoteChar}{$res[0]}{$this->dbQuoteChar} (" . implode(",", $res[1]) . ",addr_type) values (" . implode(",", $vals) . ")", $this->db)) {
|
||||
throw new DBIPException("database error: cannot insert row");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function doLookup($tableName, $addrType, $addrStart) {
|
||||
$q = mysql_query("select * from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar} where addr_type = '{$addrType}' and ip_start <= '" . mysql_real_escape_string($addrStart) . "' order by ip_start desc limit 1", $this->db);
|
||||
$r = mysql_fetch_object($q);
|
||||
mysql_free_result($q);
|
||||
return $r;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* DBIP MySQLI class
|
||||
*
|
||||
* If you are using a MySQL database backend, please prefer the DBIP base class which uses the PDO mysql driver.
|
||||
* This is only meant to be used on PHP installations where PDO is disabled and the old mysqli_* interface is available.
|
||||
*/
|
||||
class DBIPMySQLI extends DBIP {
|
||||
|
||||
private $db;
|
||||
|
||||
public function __construct($db) {
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
protected function prepareImport($tableName, array $fields) {
|
||||
$q = mysqli_query($this->db, "select count(*) as cnt from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar}");
|
||||
$r = mysqli_fetch_object($q);
|
||||
mysqli_free_result($q);
|
||||
if ($r->cnt) {
|
||||
throw new DBIPException("table {$tableName} is not empty");
|
||||
}
|
||||
return array($tableName, $fields);
|
||||
}
|
||||
|
||||
protected function finalizeImport() {
|
||||
}
|
||||
|
||||
protected function importRow($res, $row) {
|
||||
$vals = array();
|
||||
foreach ($row as $val) {
|
||||
$vals[] = "'" . mysqli_real_escape_string($this->db, $val) . "'";
|
||||
}
|
||||
if (!mysqli_query($this->db, "insert into {$this->dbQuoteChar}{$res[0]}{$this->dbQuoteChar} (" . implode(",", $res[1]) . ",addr_type) values (" . implode(",", $vals) . ")")) {
|
||||
throw new DBIPException("database error: cannot insert row");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function doLookup($tableName, $addrType, $addrStart) {
|
||||
$q = mysqli_query($this->db, "select * from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar} where addr_type = '{$addrType}' and ip_start <= '" . mysqli_real_escape_string($this->db, $addrStart) . "' order by ip_start desc limit 1");
|
||||
$r = mysqli_fetch_object($q);
|
||||
mysqli_free_result($q);
|
||||
return $r;
|
||||
}
|
||||
|
||||
}
|
||||
96
app/Services/dbip/import.php
Executable file
96
app/Services/dbip/import.php
Executable file
|
|
@ -0,0 +1,96 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com database import script
|
||||
*
|
||||
* Copyright (C) 2018 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
require "dbip.class.php";
|
||||
|
||||
$opts = getopt("f:d:t:b:u:p:");
|
||||
|
||||
$filename = @$opts["f"];
|
||||
$type = @$opts["d"];
|
||||
|
||||
$dbname = @$opts["b"]
|
||||
or $dbname = "mivita";
|
||||
|
||||
$table = @$opts["t"]
|
||||
or $table = "dbip_lookup_2"; //
|
||||
|
||||
$username = @$opts["u"]
|
||||
or $username = "kadmin";
|
||||
|
||||
$password = @$opts["p"]
|
||||
or $password = "KT32vQ7ix";
|
||||
|
||||
$host = "192.168.1.8";
|
||||
|
||||
//https://db-ip.com/db/download/ip-to-country-lite
|
||||
$filename = "dbip-country-lite-2024-07.csv";
|
||||
$table = "dbip_lookup";
|
||||
|
||||
//https://ipinfo.io/account/data-downloads
|
||||
$filename = "dbip-country-ipinfo-2024.csv";
|
||||
$table = "dbip_lookup_2";
|
||||
|
||||
if (!isset($type) && preg_match('/dbip-(country-lite|country-ipinfo|city-lite|country|location|isp|full)/i', $filename, $res)) {
|
||||
$type = $res[1];
|
||||
}
|
||||
|
||||
if (!isset($filename) || !isset($type)) {
|
||||
die("usage: {$argv[0]} -f <filename.csv[.gz]> [-d <country-lite|city-lite|country|location|isp|full>] [-b <database_name>] [-t <table_name>] [-u <username>] [-p <password>]\n");
|
||||
}
|
||||
|
||||
switch (strtolower($type)) {
|
||||
case "country-lite": $dbtype = DBIP::TYPE_COUNTRY_LITE; break;
|
||||
case "country-ipinfo": $dbtype = DBIP::TYPE_COUNTRY_IPINFO; break;
|
||||
case "city-lite": $dbtype = DBIP::TYPE_CITY_LITE; break;
|
||||
case "country": $dbtype = DBIP::TYPE_COUNTRY; break;
|
||||
case "location": $dbtype = DBIP::TYPE_LOCATION; break;
|
||||
case "isp": $dbtype = DBIP::TYPE_ISP; break;
|
||||
case "full": $dbtype = DBIP::TYPE_FULL; break;
|
||||
default: echo "invalid database type\n"; exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
// Connect to the database
|
||||
$db = new PDO("mysql:{$host}=localhost;dbname={$dbname};charset=utf8mb4", $username, $password);
|
||||
// Alternatively connect to MySQL using the old interface
|
||||
// Comment the PDO statement above and uncomment the mysql_ calls
|
||||
// below if your PHP installation doesn't support PDO :
|
||||
// $db = mysql_connect("localhost", $username, $password);
|
||||
// mysql_select_db($dbname, $db);
|
||||
|
||||
// Instanciate a new DBIP object with the database connection
|
||||
$dbip = new DBIP($db); //DBIPMySQLI
|
||||
// Alternatively instanciate a DBIP_MySQL object
|
||||
// Comment the new statement above and uncomment below if your PHP
|
||||
// installation doesn't support PDO :
|
||||
// $dbip = new DBIPMySQL($db);
|
||||
|
||||
$nrecs = $dbip->importFromCsv($filename, $dbtype, $table, function($progress) {
|
||||
echo "\r{$progress} ...";
|
||||
});
|
||||
echo "\rfinished importing " . number_format($nrecs) . " records\n";
|
||||
} catch (DBIPException $e) {
|
||||
echo "error: {$e->getMessage()}\n";
|
||||
}
|
||||
73
app/Services/dbip/lookup-example.php
Executable file
73
app/Services/dbip/lookup-example.php
Executable file
|
|
@ -0,0 +1,73 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com database sample query code
|
||||
*
|
||||
* Copyright (C) 2018 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
// Include the DB-IP class
|
||||
require "dbip.class.php";
|
||||
|
||||
$host = "192.168.1.8";
|
||||
$dbname = "mivita";
|
||||
$username = "kadmin";
|
||||
$password = "KT32vQ7ix";
|
||||
|
||||
$table = "dbip_lookup";
|
||||
$table_2 = "dbip_lookup_2";
|
||||
|
||||
try {
|
||||
|
||||
// Check if we have a command line parameter
|
||||
if ($argc < 2) {
|
||||
die("usage: {$argv[0]} <ip_address>\n");
|
||||
}
|
||||
|
||||
// Connect to the database
|
||||
$db = new PDO("mysql:{$host}=localhost;dbname={$dbname};charset=utf8mb4", $username, $password);
|
||||
|
||||
// Alternatively connect to MySQL using the old interface
|
||||
// Comment the PDO statement above and uncomment the mysql_ calls
|
||||
// below if your PHP installation doesn't support PDO :
|
||||
// $db = mysql_connect("localhost", "root", "");
|
||||
// mysql_select_db("test", $db);
|
||||
|
||||
// Instanciate a new DBIP object with the database connection
|
||||
$dbip = new DBIP($db);
|
||||
|
||||
// Alternatively instanciate a DBIP_MySQL object
|
||||
// Comment the new statement above and uncomment below if your PHP
|
||||
// installation doesn't support PDO :
|
||||
// $dbip = new DBIPMySQL($db);
|
||||
|
||||
// Lookup an IP address
|
||||
$inf = $dbip->lookup($argv[1], $table);
|
||||
// Show the associated country
|
||||
echo "t:".$table." country = " . $inf->country . "\n";
|
||||
|
||||
$inf = $dbip->lookup($argv[1], $table_2);
|
||||
// Show the associated country
|
||||
echo "t:".$table_2." country = " . $inf->country . "\n";
|
||||
|
||||
} catch (DBIPException $e) {
|
||||
echo "error: {$e->getMessage()}\n";
|
||||
exit(1);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue