src/CarCutter/ConfigManager.php line 438

Open in your IDE?
  1. <?php
  2. /**
  3.  * Carcutter Data Platform
  4.  * Configuration Manager
  5.  */
  6. namespace App\CarCutter;
  7. use League\Flysystem\FilesystemAdapter;
  8. use League\Flysystem\Filesystem;
  9. use League\Flysystem\Ftp\FtpAdapter;
  10. use Pimcore\Model\DataObject\CustomerConfig;
  11. use League\Flysystem\PhpseclibV3\SftpAdapter;
  12. use League\Flysystem\PhpseclibV3\SftpConnectionProvider;
  13. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnAutoGestion;
  14. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnBee2Link;
  15. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnFTPSettings;
  16. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnKeplerVO;
  17. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnPlanetVO;
  18. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnHomeNet;
  19. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnMaxDigital;
  20. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnDAT;
  21. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnProMax;
  22. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnDealerSearch;
  23. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnDealersync;
  24. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnCarbase;
  25. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnWayke;
  26. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnFastback;
  27. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnAutoTelex;
  28. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnOpenFlex;
  29. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnWebhook;
  30. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnDealerCenter;
  31. use Pimcore\Model\DataObject\Fieldcollection\Data\ConnMotorFlash;
  32. use Throwable;
  33. class ConfigManager
  34. {
  35.     public static function loadConfigByName(string $name) : ?CustomerConfig
  36.     {
  37.         $list = new CustomerConfig\Listing();
  38.         $list->setCondition('name = :name and enabled = 1', [
  39.             'name' => $name
  40.         ]);
  41.         if($results $list->load()) {
  42.             return $results[0];
  43.         }
  44.         return null;
  45.     }
  46.     public static function loadConfigByToken(string $token) : ?CustomerConfig
  47.     {
  48.         $list = new CustomerConfig\Listing();
  49.         $list->setCondition('token = :token and enabled = 1', [
  50.             'token' => $token
  51.         ]);
  52.         if($results $list->load()) {
  53.             return $results[0];
  54.         }
  55.         return null;
  56.     }
  57.     public static function loadAllConfigsByToken(string $token): array
  58.     {
  59.         $list = new CustomerConfig\Listing();
  60.         $list->setCondition('token = :token AND enabled = 1', [
  61.             'token' => $token
  62.         ]);
  63.         return $list->load();
  64.     }
  65.     public static function loadValidConfigs() : array
  66.     {
  67.         $list = new CustomerConfig\Listing();
  68.         $list->setCondition('enabled = 1');
  69.         return $list->load();
  70.     }
  71.     public static function getUploadAdapter(CustomerConfig $configstring $type ''bool $raw false) : mixed
  72.     {
  73.         return self::getAdapter($config, ['out''bi'], $type$raw);
  74.     }
  75.     
  76.     public static function getProMaxAdapter(CustomerConfig $config) : mixed
  77.     {
  78.         $availableConnections self::getConnections($configConnProMax::class, []);
  79.         if(count($availableConnections) > 0) {
  80.             return $availableConnections;
  81.         }
  82.         return null;
  83.     }
  84.     public static function getDealerCarSearchAdapter(CustomerConfig $config) : mixed
  85.     {
  86.         $availableConnections self::getConnections($configConnDealerSearch::class, []);
  87.         echo count($availableConnections)." DealerCarSearch Files found\n";
  88.         if(count($availableConnections) > 0) {
  89.             return $availableConnections;
  90.         }
  91.         return null;
  92.     }
  93.     public static function getDealerSyncAdapter(CustomerConfig $config) : mixed
  94.     {
  95.         $availableConnections self::getConnections($configConnDealersync::class, []);
  96.         // echo count($availableConnections)." DealerCarSearch Files found\n";
  97.         if(count($availableConnections) > 0) {
  98.             return $availableConnections;
  99.         }
  100.         return null;
  101.     }
  102.     public static function getDownloadAdapter(CustomerConfig $configstring $type ''bool $raw false) : ?FilesystemAdapter
  103.     {
  104.         return self::getAdapter($config, ['in''bi'], $type$raw);
  105.     }
  106.     public static function getBeelinkAdapter(CustomerConfig $config) : mixed
  107.     {
  108.         $availableConnections self::getConnections($configConnBee2Link::class, []);
  109.         if(count($availableConnections) > 0) {
  110.             return $availableConnections;
  111.         }
  112.         return null;
  113.     }
  114.     public static function getOpenFlexAdapter(CustomerConfig $config) : mixed
  115.     {
  116.         $availableConnections self::getConnections($configConnOpenFlex::class, []);
  117.         if(count($availableConnections) > 0) {
  118.             return $availableConnections;
  119.         }
  120.         return null;
  121.     }
  122.     
  123.     public static function getCarBaseAdapter(CustomerConfig $config) : mixed
  124.     {
  125.         $availableConnections self::getConnections($configConnCarbase::class, []);
  126.         if(count($availableConnections) > 0) {
  127.             return $availableConnections;
  128.         }
  129.         return null;
  130.     }
  131.     public static function getWebhookAdapter(CustomerConfig $config) : mixed
  132.     {
  133.         $availableConnections self::getConnections($configConnWebhook::class, []);
  134.         if(count($availableConnections) > 0) {
  135.             return $availableConnections;
  136.         }
  137.         return null;
  138.     }
  139.     public static function getFastbackAdapter(CustomerConfig $config) : mixed
  140.     {
  141.         $availableConnections self::getConnections($configConnFastback::class, []);
  142.         if(count($availableConnections) > 0) {
  143.             echo count($availableConnections)." Fastback connections found\n";
  144.             return $availableConnections;
  145.         }
  146.         return null;
  147.     }
  148.     public static function getWaykeAdapter(CustomerConfig $config) : mixed
  149.     {
  150.         $availableConnections self::getConnections($configConnWayke::class, []);
  151.         if(count($availableConnections) > 0) {
  152.             return $availableConnections;
  153.         }
  154.         return null;
  155.     }
  156.     public static function getDATAdapter(CustomerConfig $config) : mixed
  157.     {
  158.         $availableConnections self::getConnections($configConnDAT::class, []);
  159.         if(count($availableConnections) > 0) {
  160.             echo count($availableConnections)." DAT connections found\n";
  161.             return $availableConnections;
  162.         }
  163.         return null;
  164.     }
  165.     public static function getPlanetVoAdapter(CustomerConfig $config) : mixed
  166.     {
  167.         $availableConnections self::getConnections($configConnPlanetVO::class, []);
  168.         if(count($availableConnections) > 0)
  169.         {
  170.             echo count($availableConnections)." PVO connections found\n";
  171.             return $availableConnections;
  172.         }
  173.         return null;
  174.     }
  175.     public static function getAutoTelexAdapter(CustomerConfig $config) : mixed
  176.     {
  177.         $availableConnections self::getConnections($configConnAutoTelex::class, []);
  178.         if(count($availableConnections) > 0)
  179.         {
  180.             echo count($availableConnections)." AutoTelex connections found\n";
  181.             return $availableConnections;
  182.         }
  183.         return null;
  184.     }
  185.     public static function getKeplerVOAdapter(CustomerConfig $config) : ?ConnKeplerVO
  186.     {
  187.         $availableConnections self::getConnections($configConnKeplerVO::class, []);
  188.         if(count($availableConnections) > 0)
  189.         {
  190.             return array_pop($availableConnections);
  191.         }
  192.         return null;
  193.     }
  194.     public static function getHomeNetAdapter(CustomerConfig $config) : mixed
  195.     {
  196.         $availableConnections self::getConnections($configConnHomeNet::class, []);
  197.         if(count($availableConnections) > 0)
  198.         {
  199.             return $availableConnections;
  200.         }
  201.         //echo "no HomeNet connections found\n";
  202.         return null;
  203.     }
  204.     
  205.     
  206.     public static function getMaxDigitalAdapter(CustomerConfig $config) : mixed
  207.     {
  208.         $availableConnections self::getConnections($configConnMaxDigital::class, []);
  209.         if(count($availableConnections) > 0)
  210.         {
  211.             return $availableConnections;
  212.         }
  213.         //echo "no HomeNet connections found\n";
  214.         return null;
  215.     }
  216.     private static function getAdapter(CustomerConfig $config, array $directionsstring $type ''bool $raw false) : mixed
  217.     {
  218.         $availableConnections self::getConnections($config$type$directions);
  219.         if(count($availableConnections) > 0) {
  220.             $probe array_pop($availableConnections);
  221.             if(!$raw && $probe::class === ConnFTPSettings::class)
  222.             {
  223.                 return self::getFtpAdapter($probe);
  224.             }
  225.             elseif ($raw && $probe::class === ConnFTPSettings::class)
  226.             {
  227.                 return $probe;
  228.             }
  229.         }
  230.         return null;
  231.     }
  232.     public static function getFtpAdapter(ConnFTPSettings $config) : ?FtpAdapter
  233.     {
  234.         return new FtpAdapter(
  235.             // Connection options
  236.             \League\Flysystem\Ftp\FtpConnectionOptions::fromArray([
  237.                 'host' => $config->getHostName(), // required
  238.                 'root' => $config->getBaseFolder(), // required
  239.                 'username' => $config->getUser(), // required
  240.                 'password' => $config->getPassword(), // required
  241.                 'port' => intval($config->getPort()),
  242.                 'ssl' => $config->getSsl(),
  243.                 'timeout' => 90,
  244.                 'utf8' => $config->getUseUtf(),
  245.                 'passive' => true,
  246.                 'transferMode' => FTP_BINARY,
  247.                 'systemType' => null// 'windows' or 'unix'
  248.                 'ignorePassiveAddress' => $config->getIgnorePassiveAddress(), // true or false
  249.                 'timestampsOnUnixListingsEnabled' => false// true or false
  250.                 'recurseManually' => true // true
  251.             ])
  252.         );
  253.     }
  254.     public static function getOpenSshKeyContent(): string
  255.     {
  256.         // Your Ed25519 key in OpenSSH format
  257.         return '
  258. -----BEGIN OPENSSH PRIVATE KEY-----
  259. b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
  260. QyNTUxOQAAACBsrD0ryU8Z6Kpxqp+oqq1l8IazPkIgBSu4dAPmDUjWywAAAJAsMenSLDHp
  261. 0gAAAAtzc2gtZWQyNTUxOQAAACBsrD0ryU8Z6Kpxqp+oqq1l8IazPkIgBSu4dAPmDUjWyw
  262. AAAEAOggxruNr75XIGp8lF0g7SMUt/WnIs8/foHcpD4aX47WysPSvJTxnoqnGqn6iqrWXw
  263. hrM+QiAFK7h0A+YNSNbLAAAACmNhcmNlbnRyYWwBAgM=
  264. -----END OPENSSH PRIVATE KEY-----
  265.         ';
  266.     }
  267.     public static function findLatestDealerCenterFile(Filesystem $filesystemstring $dealerId): ?string
  268. {
  269.     try {
  270.         echo "[DEBUG] Searching for DealerCenter files with dealer ID: '$dealerId'\n";
  271.         
  272.         $files $filesystem->listContents('/'false);
  273.         $dealerCenterFiles = [];
  274.         
  275.         foreach ($files as $file) {
  276.             if ($file->isFile()) {
  277.                 $fileName basename($file->path());
  278.                 
  279.                 if (preg_match("/^DealerCenter[_\s](\d{8})[_\s](\d+)\.csv$/i"$fileName$matches)) {
  280.                     $fileDate $matches[1];
  281.                     $fileDealerId $matches[2];
  282.                     
  283.                     echo "[DEBUG] Found file: $fileName (date: $fileDate, dealer: $fileDealerId)\n";
  284.                     
  285.                     // Compare dealer IDs
  286.                     if ($fileDealerId === $dealerId) {
  287.                         $dealerCenterFiles[$fileDate] = $file->path();
  288.                         echo "[DEBUG] ✓ File matches dealer ID '$dealerId'\n";
  289.                     }
  290.                 }
  291.             }
  292.         }
  293.         
  294.         if (empty($dealerCenterFiles)) {
  295.             echo "❌ No DealerCenter files found for dealer ID: $dealerId\n";
  296.             echo "[DEBUG] Make sure the dealer ID is numeric and matches the filename pattern.\n";
  297.             return null;
  298.         }
  299.         
  300.         // Get the latest file by date (newest first)
  301.         krsort($dealerCenterFiles);
  302.         $latestDate array_key_first($dealerCenterFiles);
  303.         $latestFile $dealerCenterFiles[$latestDate];
  304.         
  305.         echo "✅ Found latest DealerCenter file: $latestFile (date: $latestDate)\n";
  306.         return $latestFile;
  307.         
  308.     } catch (Exception $e) {
  309.         echo "❌ Error finding DealerCenter files: " $e->getMessage() . "\n";
  310.         return null;
  311.     }
  312. }
  313.     //public static function findLatestDealerCenterFile(Filesystem $filesystem, string $dealerId): ?string
  314.     //{
  315.     //    try {
  316.     //        $files = $filesystem->listContents('/', false);
  317.     //        $dealerCenterFiles = [];
  318.     //        
  319.     //        foreach ($files as $file) {
  320.     //            $fileName = basename($file->path());
  321.     //            if ($file->isFile() && preg_match("/^DealerCenter_(\d{8})_{$dealerId}\.csv$/", $fileName, $matches)) {
  322.     //                $dealerCenterFiles[$matches[1]] = $file->path();
  323.     //            }
  324.     //        }
  325.     //        
  326.     //        if (empty($dealerCenterFiles)) {
  327.     //            echo "No DealerCenter files found for dealer ID: $dealerId\n";
  328.     //            return null;
  329.     //        }
  330.     //        
  331.     //        // Get the latest file by date
  332.     //        ksort($dealerCenterFiles);
  333.     //        $latestDate = array_key_last($dealerCenterFiles);
  334.     //        $latestFile = $dealerCenterFiles[$latestDate];
  335.     //        
  336.     //        echo "Found latest DealerCenter file: $latestFile (date: $latestDate)\n";
  337.     //        return $latestFile;
  338.     //        
  339.     //    } catch (Exception $e) {
  340.     //        echo "Error finding DealerCenter files: " . $e->getMessage() . "\n";
  341.     //        return null;
  342.     //    }
  343.     //}
  344.     
  345.     public static function getSftpAdapter(array $config): ?SftpAdapter
  346.     {
  347.         
  348.         try {
  349.             //  to be handled such that it takes token / client type and rerturn respective key
  350.             // $inst = new self();
  351.             // $privateKey = self::getOpenSshKeyContent();
  352.             print_r($config['user']);
  353.             $connectionProvider = new SftpConnectionProvider(
  354.                 $config['host'],
  355.                 $config['user'],
  356.                 $config['password'] ?: null,
  357.                 $config['openssh_key'] ?: null,
  358.                 null ,
  359.                 intval($config['port'] ?: 22),
  360.                 false,   // use agent
  361.                 30,      // timeout
  362.                 10,      // max tries
  363.                 null,    // host fingerprint
  364.                 null     // connectivity checker
  365.             );
  366.             $adapter = new SftpAdapter(
  367.                 $connectionProvider,
  368.                  '/'
  369.             );
  370.             // ✅ Verify connectivity by trying a simple operation
  371.             $filesystem = new Filesystem($adapter);
  372.             $filesystem->listContents('.'false);
  373.             // echo" File system -> "+$filesystem;
  374.             return $adapter;
  375.         } catch (Throwable $e) {
  376.             // ❌ Handle connection/adapter errors gracefully
  377.             error_log("SFTP connection failed: " $e->getMessage());
  378.             echo "❌ Error: " $e->getMessage() . PHP_EOL;
  379.             print_r($e->getTrace());
  380.             return null;  // or throw new \RuntimeException("SFTP Error: " . $e->getMessage());
  381.         }
  382.     }
  383.     public static function getConnections(CustomerConfig $configstring $type '', array $directions) : mixed
  384.     {
  385.         $connections $config->getConnections();
  386.         if($connections->getCount() === 0) {
  387.             return [];
  388.         }
  389.         $connItems $connections->getItems();
  390.         $availableConnections array_filter($connItems, function($c) use ($type$directions) {
  391.             if($type === '' || $c::class === $type) {
  392.                 if(method_exists($c'getDirection')) {
  393.                     if(in_array($c->getDirection(), $directions)) {
  394.                         return true;
  395.                     }
  396.                 } else {
  397.                     return true;
  398.                 }
  399.             }
  400.             return false;
  401.         });
  402.         return $availableConnections;
  403.     }
  404.     public static function getDealerCenterAdapter($config): array
  405.     {
  406.         $connections $config->getConnections();
  407.         $dealerCenterConnections = [];
  408.         if ($connections) {
  409.             foreach ($connections->getItems() as $item) {
  410.                 if ($item instanceof ConnDealerCenter) {
  411.                     $dealerCenterConnections[] = $item;
  412.                 }
  413.             }
  414.         }
  415.         return $dealerCenterConnections;
  416.     }
  417.     public static function getMotorFlashAdapter(CustomerConfig $config) : mixed
  418.     {
  419.         $availableConnections self::getConnections($configConnMotorFlash::class, []);
  420.         if(count($availableConnections) > 0) {
  421.             echo count($availableConnections)." MotorFlash connections found\n";
  422.             return $availableConnections;
  423.         }
  424.         return null;
  425.     }
  426. }
  427.