src/Eccube/Controller/Admin/Store/PluginController.php line 115

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.ec-cube.co.jp/
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Eccube\Controller\Admin\Store;
  13. use Eccube\Common\Constant;
  14. use Eccube\Controller\AbstractController;
  15. use Eccube\Entity\BaseInfo;
  16. use Eccube\Entity\Plugin;
  17. use Eccube\Exception\PluginApiException;
  18. use Eccube\Exception\PluginException;
  19. use Eccube\Form\Type\Admin\AuthenticationType;
  20. use Eccube\Form\Type\Admin\PluginLocalInstallType;
  21. use Eccube\Form\Type\Admin\PluginManagementType;
  22. use Eccube\Repository\BaseInfoRepository;
  23. use Eccube\Repository\PluginRepository;
  24. use Eccube\Service\Composer\ComposerServiceInterface;
  25. use Eccube\Service\PluginApiService;
  26. use Eccube\Service\PluginService;
  27. use Eccube\Service\SystemService;
  28. use Eccube\Util\CacheUtil;
  29. use Eccube\Util\StringUtil;
  30. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  31. use Symfony\Component\DependencyInjection\Container;
  32. use Symfony\Component\Filesystem\Filesystem;
  33. use Symfony\Component\Finder\Finder;
  34. use Symfony\Component\HttpFoundation\File\UploadedFile;
  35. use Symfony\Component\HttpFoundation\JsonResponse;
  36. use Symfony\Component\HttpFoundation\RedirectResponse;
  37. use Symfony\Component\HttpFoundation\Request;
  38. use Symfony\Component\Routing\Annotation\Route;
  39. use Symfony\Component\Routing\Exception\RouteNotFoundException;
  40. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  41. class PluginController extends AbstractController
  42. {
  43.     /**
  44.      * @var PluginService
  45.      */
  46.     protected $pluginService;
  47.     /**
  48.      * @var BaseInfo
  49.      */
  50.     protected $BaseInfo;
  51.     /**
  52.      * @var PluginRepository
  53.      */
  54.     protected $pluginRepository;
  55.     /**
  56.      * @var PluginApiService
  57.      */
  58.     protected $pluginApiService;
  59.     /**
  60.      * @var ComposerServiceInterface
  61.      */
  62.     private $composerService;
  63.     /**
  64.      * @var SystemService
  65.      */
  66.     private $systemService;
  67.     /**
  68.      * PluginController constructor.
  69.      *
  70.      * @param PluginRepository $pluginRepository
  71.      * @param PluginService $pluginService
  72.      * @param BaseInfoRepository $baseInfoRepository
  73.      * @param PluginApiService $pluginApiService
  74.      * @param ComposerServiceInterface $composerService
  75.      *
  76.      * @throws \Doctrine\ORM\NoResultException
  77.      * @throws \Doctrine\ORM\NonUniqueResultException
  78.      */
  79.     public function __construct(
  80.         PluginRepository $pluginRepository,
  81.         PluginService $pluginService,
  82.         BaseInfoRepository $baseInfoRepository,
  83.         PluginApiService $pluginApiService,
  84.         ComposerServiceInterface $composerService,
  85.         SystemService $systemService
  86.     ) {
  87.         $this->pluginRepository $pluginRepository;
  88.         $this->pluginService $pluginService;
  89.         $this->BaseInfo $baseInfoRepository->get();
  90.         $this->pluginApiService $pluginApiService;
  91.         $this->composerService $composerService;
  92.         $this->systemService $systemService;
  93.     }
  94.     /**
  95.      * インストール済プラグイン画面
  96.      *
  97.      * @Route("/%eccube_admin_route%/store/plugin", name="admin_store_plugin", methods={"GET"})
  98.      * @Template("@admin/Store/plugin.twig")
  99.      *
  100.      * @return array
  101.      *
  102.      * @throws PluginException
  103.      */
  104.     public function index()
  105.     {
  106.         $pluginForms = [];
  107.         $configPages = [];
  108.         $Plugins $this->pluginRepository->findBy([], ['code' => 'ASC']);
  109.         // ファイル設置プラグインの取得.
  110.         $unregisteredPlugins $this->getUnregisteredPlugins($Plugins);
  111.         $unregisteredPluginsConfigPages = [];
  112.         foreach ($unregisteredPlugins as $unregisteredPlugin) {
  113.             try {
  114.                 $code $unregisteredPlugin['code'];
  115.                 // プラグイン用設定画面があれば表示(プラグイン用のサービスプロバイダーに定義されているか)
  116.                 $unregisteredPluginsConfigPages[$code] = $this->generateUrl('plugin_'.$code.'_config');
  117.             } catch (RouteNotFoundException $e) {
  118.                 // プラグインで設定画面のルートが定義されていない場合は無視
  119.             }
  120.         }
  121.         $officialPlugins = [];
  122.         $unofficialPlugins = [];
  123.         foreach ($Plugins as $Plugin) {
  124.             $form $this->formFactory
  125.                 ->createNamedBuilder(
  126.                     'form'.$Plugin->getId(),
  127.                     PluginManagementType::class,
  128.                     null,
  129.                     [
  130.                         'plugin_id' => $Plugin->getId(),
  131.                     ]
  132.                 )
  133.                 ->getForm();
  134.             $pluginForms[$Plugin->getId()] = $form->createView();
  135.             try {
  136.                 // プラグイン用設定画面があれば表示(プラグイン用のサービスプロバイダーに定義されているか)
  137.                 $configPages[$Plugin->getCode()] = $this->generateUrl(Container::underscore($Plugin->getCode()).'_admin_config');
  138.             } catch (\Exception $e) {
  139.                 // プラグインで設定画面のルートが定義されていない場合は無視
  140.             }
  141.             if ($Plugin->getSource() == 0) {
  142.                 // 商品IDが設定されていない場合、非公式プラグイン
  143.                 $unofficialPlugins[] = $Plugin;
  144.             } else {
  145.                 $officialPlugins[$Plugin->getSource()] = $Plugin;
  146.             }
  147.         }
  148.         // オーナーズストア通信
  149.         $officialPluginsDetail = [];
  150.         try {
  151.             $data $this->pluginApiService->getPurchased();
  152.             foreach ($data as $item) {
  153.                 if (isset($officialPlugins[$item['id']]) === false) {
  154.                     $Plugin = new Plugin();
  155.                     $Plugin->setName($item['name']);
  156.                     $Plugin->setCode($item['code']);
  157.                     $Plugin->setVersion($item['version']);
  158.                     $Plugin->setSource($item['id']);
  159.                     $Plugin->setEnabled(false);
  160.                     $officialPlugins[$item['id']] = $Plugin;
  161.                 }
  162.                 $officialPluginsDetail[$item['id']] = $item;
  163.             }
  164.         } catch (PluginApiException $e) {
  165.             $this->addWarning($e->getMessage(), 'admin');
  166.         }
  167.         return [
  168.             'plugin_forms' => $pluginForms,
  169.             'officialPlugins' => $officialPlugins,
  170.             'unofficialPlugins' => $unofficialPlugins,
  171.             'configPages' => $configPages,
  172.             'unregisteredPlugins' => $unregisteredPlugins,
  173.             'unregisteredPluginsConfigPages' => $unregisteredPluginsConfigPages,
  174.             'officialPluginsDetail' => $officialPluginsDetail,
  175.         ];
  176.     }
  177.     /**
  178.      * インストール済プラグインからのアップデート
  179.      *
  180.      * @Route("/%eccube_admin_route%/store/plugin/{id}/update", requirements={"id" = "\d+"}, name="admin_store_plugin_update", methods={"POST"})
  181.      *
  182.      * @param Request $request
  183.      * @param Plugin $Plugin
  184.      * @param CacheUtil $cacheUtil
  185.      *
  186.      * @return RedirectResponse
  187.      */
  188.     public function update(Request $requestPlugin $PluginCacheUtil $cacheUtil)
  189.     {
  190.         $form $this->formFactory
  191.             ->createNamedBuilder(
  192.                 'form'.$Plugin->getId(),
  193.                 PluginManagementType::class,
  194.                 null,
  195.                 [
  196.                     'plugin_id' => null// placeHolder
  197.                 ]
  198.             )
  199.             ->getForm();
  200.         $message '';
  201.         $form->handleRequest($request);
  202.         if ($form->isSubmitted() && $form->isValid()) {
  203.             $tmpDir null;
  204.             try {
  205.                 $cacheUtil->clearCache();
  206.                 $formFile $form['plugin_archive']->getData();
  207.                 $tmpDir $this->pluginService->createTempDir();
  208.                 $tmpFile sha1(StringUtil::random(32)).'.'.$formFile->getClientOriginalExtension();
  209.                 $formFile->move($tmpDir$tmpFile);
  210.                 $this->pluginService->update($Plugin$tmpDir.'/'.$tmpFile);
  211.                 $fs = new Filesystem();
  212.                 $fs->remove($tmpDir);
  213.                 $this->addSuccess(trans('admin.store.plugin.update.complete', ['%plugin_name%' => $Plugin->getName()]), 'admin');
  214.                 return $this->redirectToRoute('admin_store_plugin');
  215.             } catch (PluginException $e) {
  216.                 if (!empty($tmpDir) && file_exists($tmpDir)) {
  217.                     $fs = new Filesystem();
  218.                     $fs->remove($tmpDir);
  219.                 }
  220.                 $message $e->getMessage();
  221.             } catch (\Exception $er) {
  222.                 // Catch composer install error | Other error
  223.                 if (!empty($tmpDir) && file_exists($tmpDir)) {
  224.                     $fs = new Filesystem();
  225.                     $fs->remove($tmpDir);
  226.                 }
  227.                 log_error('plugin install failed.', ['original-message' => $er->getMessage()]);
  228.                 $message trans('admin.store.plugin.update.failed', ['%plugin_name%' => $Plugin->getName()]);
  229.             }
  230.         } else {
  231.             $errors $form->getErrors(true);
  232.             foreach ($errors as $error) {
  233.                 $message $error->getMessage();
  234.             }
  235.         }
  236.         $this->addError($message'admin');
  237.         return $this->redirectToRoute('admin_store_plugin');
  238.     }
  239.     /**
  240.      * 対象のプラグインを有効にします。
  241.      *
  242.      * @Route("/%eccube_admin_route%/store/plugin/{id}/enable", requirements={"id" = "\d+"}, name="admin_store_plugin_enable", methods={"POST"})
  243.      *
  244.      * @param Plugin $Plugin
  245.      *
  246.      * @return RedirectResponse|JsonResponse
  247.      *
  248.      * @throws PluginException
  249.      */
  250.     public function enable(Plugin $PluginCacheUtil $cacheUtilRequest $request)
  251.     {
  252.         $this->isTokenValid();
  253.         // QueryString maintenance_modeがない場合
  254.         if (!$request->query->has('maintenance_mode')) {
  255.             // プラグイン管理の有効ボタンを押したとき
  256.             $this->systemService->switchMaintenance(true); // auto_maintenanceと設定されたファイルを生成
  257.         }
  258.         $cacheUtil->clearCache();
  259.         if ($Plugin->isEnabled()) {
  260.             if ($request->isXmlHttpRequest()) {
  261.                 return $this->json(['success' => true]);
  262.             } else {
  263.                 $this->addError(trans('admin.store.plugin.already.enabled', ['%plugin_name%' => $Plugin->getName()]), 'admin');
  264.                 return $this->redirectToRoute('admin_store_plugin');
  265.             }
  266.         } else {
  267.             // ストアからインストールしたプラグインは依存プラグインが有効化されているかを確認
  268.             if ($Plugin->getSource()) {
  269.                 $requires $this->pluginService->getPluginRequired($Plugin);
  270.                 $requires array_filter($requires, function ($req) {
  271.                     $code preg_replace('/^ec-cube\//i'''$req['name']);
  272.                     /** @var Plugin $DependPlugin */
  273.                     $DependPlugin $this->pluginRepository->findByCode($code);
  274.                     return $DependPlugin->isEnabled() == false;
  275.                 });
  276.                 if (!empty($requires)) {
  277.                     $names array_map(function ($req) {
  278.                         return "「${req['description']}」";
  279.                     }, $requires);
  280.                     $message trans('%depend_name%を先に有効化してください。', ['%name%' => $Plugin->getName(), '%depend_name%' => implode(', '$names)]);
  281.                     if ($request->isXmlHttpRequest()) {
  282.                         return $this->json(['success' => false'message' => $message], 400);
  283.                     } else {
  284.                         $this->addError($message'admin');
  285.                         $this->addFlash('eccube.admin.disable_maintenance''');
  286.                         return $this->redirectToRoute('admin_store_plugin');
  287.                     }
  288.                 }
  289.             }
  290.             try {
  291.                 ob_start();
  292.                 if (!$Plugin->isInitialized()) {
  293.                     $this->pluginService->installWithCode($Plugin->getCode());
  294.                 }
  295.                 $this->pluginService->enable($Plugin);
  296.             } finally {
  297.                 $log ob_get_clean();
  298.                 while (ob_get_level() > 0) {
  299.                     ob_end_flush();
  300.                 }
  301.             }
  302.         }
  303.         if ($request->isXmlHttpRequest()) {
  304.             return $this->json(['success' => true'log' => $log]);
  305.         } else {
  306.             $this->addSuccess(trans('admin.store.plugin.enable.complete', ['%plugin_name%' => $Plugin->getName()]), 'admin');
  307.             $this->addFlash('eccube.admin.disable_maintenance''');
  308.             return $this->redirectToRoute('admin_store_plugin');
  309.         }
  310.     }
  311.     /**
  312.      * 対象のプラグインを無効にします。
  313.      *
  314.      * @Route("/%eccube_admin_route%/store/plugin/{id}/disable", requirements={"id" = "\d+"}, name="admin_store_plugin_disable", methods={"POST"})
  315.      *
  316.      * @param Request $request
  317.      * @param Plugin $Plugin
  318.      * @param CacheUtil $cacheUtil
  319.      *
  320.      * @return \Symfony\Component\HttpFoundation\JsonResponse|RedirectResponse
  321.      */
  322.     public function disable(Request $requestPlugin $PluginCacheUtil $cacheUtil)
  323.     {
  324.         $this->isTokenValid();
  325.         // QueryString maintenance_modeであるか確認
  326.         $mentenance_mode $request->query->get('maintenance_mode');
  327.         // プラグイン管理でアップデートが実行されたとき
  328.         if (SystemService::AUTO_MAINTENANCE_UPDATE == $mentenance_mode) {
  329.             $this->systemService->switchMaintenance(trueSystemService::AUTO_MAINTENANCE_UPDATE); // auto_maintenance_updateと設定されたファイルを生成
  330.         } else {
  331.             // プラグイン管理で無効ボタンを押したとき
  332.             $this->systemService->switchMaintenance(true); // auto_maintenanceと設定されたファイルを生成
  333.         }
  334.         $cacheUtil->clearCache();
  335.         $log null;
  336.         if ($Plugin->isEnabled()) {
  337.             $dependents $this->pluginService->findDependentPluginNeedDisable($Plugin->getCode());
  338.             if (!empty($dependents)) {
  339.                 $dependName $dependents[0];
  340.                 $DependPlugin $this->pluginRepository->findOneBy(['code' => $dependents[0]]);
  341.                 if ($DependPlugin) {
  342.                     $dependName $DependPlugin->getName();
  343.                 }
  344.                 $message trans('admin.plugin.disable.depend', ['%name%' => $Plugin->getName(), '%depend_name%' => $dependName]);
  345.                 if ($request->isXmlHttpRequest()) {
  346.                     return $this->json(['message' => $message], 400);
  347.                 } else {
  348.                     $this->addError($message'admin');
  349.                     $this->addFlash('eccube.admin.disable_maintenance''');
  350.                     return $this->redirectToRoute('admin_store_plugin');
  351.                 }
  352.             }
  353.             try {
  354.                 ob_start();
  355.                 $this->pluginService->disable($Plugin);
  356.             } finally {
  357.                 $log ob_get_clean();
  358.                 while (ob_get_level() > 0) {
  359.                     ob_end_flush();
  360.                 }
  361.             }
  362.         } else {
  363.             if ($request->isXmlHttpRequest()) {
  364.                 return $this->json(['success' => true'log' => $log]);
  365.             } else {
  366.                 $this->addError(trans('admin.store.plugin.already.disabled', ['%plugin_name%' => $Plugin->getName()]), 'admin');
  367.                 return $this->redirectToRoute('admin_store_plugin');
  368.             }
  369.         }
  370.         if ($request->isXmlHttpRequest()) {
  371.             return $this->json(['success' => true'log' => $log]);
  372.         } else {
  373.             $this->addSuccess(trans('admin.store.plugin.disable.complete', ['%plugin_name%' => $Plugin->getName()]), 'admin');
  374.             $this->addFlash('eccube.admin.disable_maintenance''');
  375.             return $this->redirectToRoute('admin_store_plugin');
  376.         }
  377.     }
  378.     /**
  379.      * 対象のプラグインを削除します。
  380.      *
  381.      * @Route("/%eccube_admin_route%/store/plugin/{id}/uninstall", requirements={"id" = "\d+"}, name="admin_store_plugin_uninstall", methods={"DELETE"})
  382.      *
  383.      * @param Plugin $Plugin
  384.      * @param CacheUtil $cacheUtil
  385.      *
  386.      * @return RedirectResponse
  387.      *
  388.      * @throws \Exception
  389.      */
  390.     public function uninstall(Plugin $PluginCacheUtil $cacheUtil)
  391.     {
  392.         $this->isTokenValid();
  393.         if ($Plugin->isEnabled()) {
  394.             $this->addError('admin.plugin.uninstall.error.not_disable''admin');
  395.             return $this->redirectToRoute('admin_store_plugin');
  396.         }
  397.         // Check other plugin depend on it
  398.         $pluginCode $Plugin->getCode();
  399.         $otherDepend $this->pluginService->findDependentPlugin($pluginCode);
  400.         if (!empty($otherDepend)) {
  401.             $DependPlugin $this->pluginRepository->findOneBy(['code' => $otherDepend[0]]);
  402.             $dependName $otherDepend[0];
  403.             if ($DependPlugin) {
  404.                 $dependName $DependPlugin->getName();
  405.             }
  406.             $message trans('admin.plugin.uninstall.depend', ['%name%' => $Plugin->getName(), '%depend_name%' => $dependName]);
  407.             $this->addError($message'admin');
  408.             return $this->redirectToRoute('admin_store_plugin');
  409.         }
  410.         $cacheUtil->clearCache();
  411.         $this->pluginService->uninstall($Plugin);
  412.         $this->addSuccess('admin.store.plugin.uninstall.complete''admin');
  413.         return $this->redirectToRoute('admin_store_plugin');
  414.     }
  415.     /**
  416.      * プラグインファイルアップロード画面
  417.      *
  418.      * @Route("/%eccube_admin_route%/store/plugin/install", name="admin_store_plugin_install", methods={"GET", "POST"})
  419.      * @Template("@admin/Store/plugin_install.twig")
  420.      *
  421.      * @param Request $request
  422.      * @param CacheUtil $cacheUtil
  423.      *
  424.      * @return array|RedirectResponse
  425.      */
  426.     public function install(Request $requestCacheUtil $cacheUtil)
  427.     {
  428.         $this->addInfoOnce('admin.common.restrict_file_upload_info''admin');
  429.         $form $this->formFactory
  430.             ->createBuilder(PluginLocalInstallType::class)
  431.             ->getForm();
  432.         $errors = [];
  433.         $form->handleRequest($request);
  434.         if ($form->isSubmitted() && $form->isValid()) {
  435.             $tmpDir null;
  436.             try {
  437.                 $cacheUtil->clearCache();
  438.                 /** @var UploadedFile $formFile */
  439.                 $formFile $form['plugin_archive']->getData();
  440.                 $tmpDir $this->pluginService->createTempDir();
  441.                 // 拡張子を付けないとpharが動かないので付ける
  442.                 $tmpFile sha1(StringUtil::random(32)).'.'.$formFile->getClientOriginalExtension();
  443.                 $formFile->move($tmpDir$tmpFile);
  444.                 $tmpPath $tmpDir.'/'.$tmpFile;
  445.                 $this->pluginService->install($tmpPath);
  446.                 // Remove tmp file
  447.                 $fs = new Filesystem();
  448.                 $fs->remove($tmpDir);
  449.                 $this->addSuccess('admin.store.plugin.install.complete''admin');
  450.                 return $this->redirectToRoute('admin_store_plugin');
  451.             } catch (PluginException $e) {
  452.                 if (!empty($tmpDir) && file_exists($tmpDir)) {
  453.                     $fs = new Filesystem();
  454.                     $fs->remove($tmpDir);
  455.                 }
  456.                 log_error('plugin install failed.', ['original-message' => $e->getMessage()]);
  457.                 $errors[] = $e;
  458.             } catch (\Exception $er) {
  459.                 // Catch composer install error | Other error
  460.                 if (!empty($tmpDir) && file_exists($tmpDir)) {
  461.                     $fs = new Filesystem();
  462.                     $fs->remove($tmpDir);
  463.                 }
  464.                 log_error('plugin install failed.', ['original-message' => $er->getMessage()]);
  465.                 $this->addError('admin.store.plugin.install.failed''admin');
  466.             }
  467.         } else {
  468.             foreach ($form->getErrors(true) as $error) {
  469.                 $errors[] = $error;
  470.             }
  471.         }
  472.         return [
  473.             'form' => $form->createView(),
  474.             'errors' => $errors,
  475.         ];
  476.     }
  477.     /**
  478.      * 認証キー設定画面
  479.      *
  480.      * @Route("/%eccube_admin_route%/store/plugin/authentication_setting", name="admin_store_authentication_setting", methods={"GET", "POST"})
  481.      * @Template("@admin/Store/authentication_setting.twig")
  482.      *
  483.      * @param Request $request
  484.      *
  485.      * @return array
  486.      */
  487.     public function authenticationSetting(Request $requestCacheUtil $cacheUtil)
  488.     {
  489.         $builder $this->formFactory
  490.             ->createBuilder(AuthenticationType::class, $this->BaseInfo);
  491.         $form $builder->getForm();
  492.         $form->handleRequest($request);
  493.         if ($form->isSubmitted() && $form->isValid()) {
  494.             // 認証キーの登録 and PHP path
  495.             $this->BaseInfo $form->getData();
  496.             $this->entityManager->persist($this->BaseInfo);
  497.             $this->entityManager->flush();
  498.             // composerの認証を更新
  499.             $this->composerService->configureRepository($this->BaseInfo);
  500.             $this->addSuccess('admin.common.save_complete''admin');
  501.             $cacheUtil->clearCache();
  502.             return $this->redirectToRoute('admin_store_authentication_setting');
  503.         }
  504.         return [
  505.             'form' => $form->createView(),
  506.             'eccubeUrl' => $this->generateUrl('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL),
  507.             'eccubeShopName' => $this->BaseInfo->getShopName(),
  508.         ];
  509.     }
  510.     /**
  511.      * フォルダ設置のみのプラグインを取得する.
  512.      *
  513.      * @param array $plugins
  514.      *
  515.      * @return array
  516.      *
  517.      * @throws PluginException
  518.      */
  519.     protected function getUnregisteredPlugins(array $plugins)
  520.     {
  521.         $finder = new Finder();
  522.         $pluginCodes = [];
  523.         // DB登録済みプラグインコードのみ取得
  524.         foreach ($plugins as $plugin) {
  525.             $pluginCodes[] = $plugin->getCode();
  526.         }
  527.         // DB登録済みプラグインコードPluginディレクトリから排他
  528.         $dirs $finder->in($this->eccubeConfig['plugin_realdir'])->depth(0)->directories();
  529.         // プラグイン基本チェック
  530.         $unregisteredPlugins = [];
  531.         foreach ($dirs as $dir) {
  532.             $pluginCode $dir->getBasename();
  533.             if (in_array($pluginCode$pluginCodestrue)) {
  534.                 continue;
  535.             }
  536.             try {
  537.                 $this->pluginService->checkPluginArchiveContent($dir->getRealPath());
  538.             } catch (PluginException $e) {
  539.                 // config.yamlに不備があった際は全てスキップ
  540.                 log_warning($e->getMessage());
  541.                 continue;
  542.             }
  543.             $config $this->pluginService->readConfig($dir->getRealPath());
  544.             $unregisteredPlugins[$pluginCode]['name'] = isset($config['name']) ? $config['name'] : null;
  545.             $unregisteredPlugins[$pluginCode]['event'] = isset($config['event']) ? $config['event'] : null;
  546.             $unregisteredPlugins[$pluginCode]['version'] = isset($config['version']) ? $config['version'] : null;
  547.             $unregisteredPlugins[$pluginCode]['enabled'] = Constant::DISABLED;
  548.             $unregisteredPlugins[$pluginCode]['code'] = isset($config['code']) ? $config['code'] : null;
  549.         }
  550.         return $unregisteredPlugins;
  551.     }
  552. }