Uname:Linux server17213-10344.hostycare.online 5.14.0-687.38.1.el9_8.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Aug 12 17:19:12 EDT 2026 x86_64

403WebShell
403Webshell
Server IP : 103.243.232.44  /  Your IP : 216.73.216.237
Web Server : LiteSpeed
System : Linux server17213-10344.hostycare.online 5.14.0-687.38.1.el9_8.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Aug 12 17:19:12 EDT 2026 x86_64
User : iamakash ( 1400)
PHP Version : 8.1.34
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/iamakash/.trash/lib/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/iamakash/.trash/lib/ExcelImporter.php
<?php
namespace Shaurya;

use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use PDO;
use RuntimeException;

/**
 * Parses a WPI monthly-index Excel file (as downloaded from eaindustry.nic.in)
 * and upserts commodities + monthly index values into the database.
 *
 * Expected layout (single sheet, usually named MONTHLY_INDEX):
 *   Row 0:  COMM_NAME | COMM_CODE | COMM_WT | INDX042012 | INDX052012 | ... | INDX022026
 *   Row 1+: one row per commodity
 *
 * Commodity hierarchy is inferred from the 10-digit COMM_CODE:
 *   - positions 0..1 = Level 2 (section)  e.g. 1100000000 = "I PRIMARY ARTICLES"
 *   - positions 0..3 = Level 3            e.g. 1101000000 = "(A). FOOD ARTICLES"
 *   - positions 0..5 = Level 4            e.g. 1101010000 = "a. FOOD GRAINS"
 *   - positions 0..7 = Level 5            e.g. 1101010100 = "a1. CEREALS"
 *   - positions 0..9 = Level 6 (leaf)     e.g. 1101010101 = "Paddy"
 *   - "1000000000" = "All commodities" is Level 2 (root, parent NULL)
 */
class ExcelImporter
{
    private PDO $pdo;
    private string $baseYear;

    public function __construct(PDO $pdo, string $baseYear = '2011-12')
    {
        $this->pdo = $pdo;
        $this->baseYear = $baseYear;
    }

    /**
     * Returns an associative summary:
     *   sheet, commodities_seen, periods_seen, values_written, latest_period, periods: [[y,m], ...]
     */
    public function import(string $filePath, ?int $uploadId = null): array
    {
        if (!is_file($filePath)) {
            throw new RuntimeException("File not found: $filePath");
        }

        $spreadsheet = IOFactory::load($filePath);
        $sheet = $this->locateDataSheet($spreadsheet);

        $highestRow = $sheet->getHighestDataRow();
        $highestCol = $sheet->getHighestDataColumn();
        $highestColIdx = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestCol);

        // --- Read header row (row 1 in 1-indexed PhpSpreadsheet coords) ---
        $headers = [];
        for ($c = 1; $c <= $highestColIdx; $c++) {
            $headers[$c] = trim((string)$sheet->getCell([$c, 1])->getValue());
        }

        $colName = $this->findHeaderColumn($headers, 'COMM_NAME');
        $colCode = $this->findHeaderColumn($headers, 'COMM_CODE');
        $colWt   = $this->findHeaderColumn($headers, 'COMM_WT');
        if (!$colName || !$colCode) {
            throw new RuntimeException(
                'Could not find COMM_NAME / COMM_CODE columns in header row. '
                . 'Header seen: ' . implode(', ', array_filter($headers))
            );
        }

        // Map INDX columns to (year, month)
        // Header like "INDX042012" → month=04, year=2012
        $indxCols = [];   // colIdx => ['y'=>int,'m'=>int,'key'=>'202204']
        foreach ($headers as $idx => $h) {
            if (preg_match('/^INDX(\d{2})(\d{4})$/', $h, $m)) {
                $mon = (int)$m[1];
                $yr  = (int)$m[2];
                if ($mon >= 1 && $mon <= 12 && $yr >= 1900) {
                    $indxCols[$idx] = [
                        'y' => $yr,
                        'm' => $mon,
                        'sortKey' => $yr * 100 + $mon,
                    ];
                }
            }
        }
        if (!$indxCols) {
            throw new RuntimeException('No INDXmmyyyy columns found in header row.');
        }

        // Identify the latest 2 periods (provisional per SOW)
        $allPeriods = array_values($indxCols);
        usort($allPeriods, fn($a, $b) => $b['sortKey'] <=> $a['sortKey']);
        $provisionalSet = [];
        foreach (array_slice($allPeriods, 0, 2) as $p) {
            $provisionalSet[$p['sortKey']] = true;
        }
        $latestPeriod = $allPeriods ? sprintf('%02d%04d', $allPeriods[0]['m'], $allPeriods[0]['y']) : null;

        // --- Prepared statements ---
        $commUpsert = $this->pdo->prepare(
            'INSERT INTO commodities
                (comm_code, comm_name, level, parent_code, comm_wt, base_year, display_name)
             VALUES (:code, :name, :level, :parent, :wt, :base, :display)
             ON DUPLICATE KEY UPDATE
                comm_name    = VALUES(comm_name),
                level        = VALUES(level),
                parent_code  = VALUES(parent_code),
                comm_wt      = VALUES(comm_wt),
                display_name = VALUES(display_name)'
        );

        $commoditiesSeen = 0;
        $valuesWritten   = 0;
        $rowBuffer       = [];    // for batched monthly_indices INSERT
        $batchSize       = 500;

        $this->pdo->beginTransaction();
        try {
            for ($r = 2; $r <= $highestRow; $r++) {
                $name = trim((string)$sheet->getCell([$colName, $r])->getValue());
                $codeRaw = $sheet->getCell([$colCode, $r])->getValue();
                if ($codeRaw === null || $codeRaw === '') continue;
                if (is_float($codeRaw)) {
                    $code = rtrim(rtrim(sprintf('%.0f', $codeRaw), '0'), '.');
                    $code = sprintf('%.0f', $codeRaw);
                } else {
                    $code = trim((string)$codeRaw);
                }
                // Normalize to 10 digits left-padded
                $code = str_pad($code, 10, '0', STR_PAD_LEFT);
                if (!preg_match('/^\d{10}$/', $code) || $name === '') {
                    continue;
                }

                $wt = $colWt ? $sheet->getCell([$colWt, $r])->getValue() : null;
                $wt = is_numeric($wt) ? (float)$wt : null;

                $level  = self::levelOf($code);
                $parent = self::parentOf($code, $level);
                $display = $code . ' - ' . $name;

                $commUpsert->execute([
                    ':code'    => $code,
                    ':name'    => $name,
                    ':level'   => $level,
                    ':parent'  => $parent,
                    ':wt'      => $wt,
                    ':base'    => $this->baseYear,
                    ':display' => $display,
                ]);
                $commoditiesSeen++;

                // Read INDX values for this commodity
                foreach ($indxCols as $idx => $p) {
                    $val = $sheet->getCell([$idx, $r])->getValue();
                    if ($val === null || $val === '') {
                        $val = null;
                    } elseif (!is_numeric($val)) {
                        continue; // skip non-numeric garbage
                    } else {
                        $val = (float)$val;
                    }
                    $isProv = isset($provisionalSet[$p['sortKey']]) ? 1 : 0;
                    $rowBuffer[] = [$code, $this->baseYear, $p['y'], $p['m'], $val, $isProv, $uploadId];
                    if (count($rowBuffer) >= $batchSize) {
                        $valuesWritten += $this->flushValues($rowBuffer);
                        $rowBuffer = [];
                    }
                }
            }
            if ($rowBuffer) {
                $valuesWritten += $this->flushValues($rowBuffer);
            }
            $this->pdo->commit();
        } catch (\Throwable $e) {
            $this->pdo->rollBack();
            throw $e;
        }

        return [
            'sheet'            => $sheet->getTitle(),
            'commodities_seen' => $commoditiesSeen,
            'periods_seen'     => count($indxCols),
            'values_written'   => $valuesWritten,
            'latest_period'    => $latestPeriod,
        ];
    }

    // ---------- helpers ----------

    private function locateDataSheet(Spreadsheet $wb): Worksheet
    {
        // Prefer a sheet literally named MONTHLY_INDEX; else any sheet whose
        // first row starts with COMM_NAME, COMM_CODE.
        foreach ($wb->getAllSheets() as $sh) {
            if (strcasecmp($sh->getTitle(), 'MONTHLY_INDEX') === 0) {
                return $sh;
            }
        }
        foreach ($wb->getAllSheets() as $sh) {
            $h1 = trim((string)$sh->getCell('A1')->getValue());
            $h2 = trim((string)$sh->getCell('B1')->getValue());
            if (strcasecmp($h1, 'COMM_NAME') === 0 && strcasecmp($h2, 'COMM_CODE') === 0) {
                return $sh;
            }
        }
        // Fall back to first sheet
        return $wb->getSheet(0);
    }

    private function findHeaderColumn(array $headers, string $needle): ?int
    {
        foreach ($headers as $idx => $h) {
            if (strcasecmp(trim($h), $needle) === 0) {
                return $idx;
            }
        }
        return null;
    }

    private function flushValues(array $rows): int
    {
        if (!$rows) return 0;
        $placeholders = rtrim(str_repeat('(?,?,?,?,?,?,?),', count($rows)), ',');
        $sql = "INSERT INTO monthly_indices
                    (comm_code, base_year, period_year, period_month, index_value, is_provisional, upload_id)
                VALUES $placeholders
                ON DUPLICATE KEY UPDATE
                    index_value    = VALUES(index_value),
                    is_provisional = VALUES(is_provisional),
                    upload_id      = VALUES(upload_id)";
        $stmt = $this->pdo->prepare($sql);
        $flat = [];
        foreach ($rows as $r) {
            foreach ($r as $v) { $flat[] = $v; }
        }
        $stmt->execute($flat);
        return count($rows);
    }

    public static function levelOf(string $code): int
    {
        $code = str_pad($code, 10, '0', STR_PAD_LEFT);
        $stripped = rtrim($code, '0');
        $tz = 10 - strlen($stripped);
        if ($tz >= 8) return 2;   // "All commodities" (tz=9) or section (tz=8)
        if ($tz >= 6) return 3;
        if ($tz >= 4) return 4;
        if ($tz >= 2) return 5;
        return 6;
    }

    public static function parentOf(string $code, int $level): ?string
    {
        if ($level <= 2) return null;
        $sig = 2 * ($level - 2); // significant digits of parent
        return substr($code, 0, $sig) . str_repeat('0', 10 - $sig);
    }
}

Youez - 2016 - github.com/yon3zu
LinuXploit