custom/plugins/SelfdelveCms/src/SelfdelveCms.php line 19

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Selfdelve\Cms;
  4. use Shopware\Core\Checkout\Shipping\ShippingMethodDefinition;
  5. use Shopware\Core\Content\Category\CategoryDefinition;
  6. use Shopware\Core\Content\Product\ProductDefinition;
  7. use Shopware\Core\Framework\Plugin;
  8. use Shopware\Core\Framework\Plugin\Context\InstallContext;
  9. use Shopware\Core\Framework\Plugin\Context\UninstallContext;
  10. use Shopware\Core\System\Country\CountryDefinition;
  11. use Shopware\Core\System\CustomField\CustomFieldTypes;
  12. use Shopware\Core\Framework\Uuid\Uuid;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  15. use Shopware\Core\Framework\Context;
  16. class SelfdelveCms extends Plugin
  17. {
  18.     private const CUSTOM_FIELDS_SET_CATEGORY 'selfdelve_theme_category';
  19.     private const CUSTOM_FIELDS_SET_CUSTOMER 'selfdelve_theme_customer';
  20.     private const CUSTOM_FIELDS_SET_PRODUCT 'selfdelve_theme_product';
  21.     private const CUSTOM_FIELDS_SET_SHIPPING_METHOD 'selfdelve_theme_shippingmethod';
  22.     private const CUSTOM_FIELD_SET_COUNTRY 'selfdelvecms-country-custom-field-set';
  23.     /**
  24.      * Installation tasks.
  25.      * @param InstallContext $installContext
  26.      */
  27.     public function install(InstallContext $installContext): void
  28.     {
  29.         $this->addCustomFieldSets($installContext->getContext());
  30.     }
  31.     /**
  32.      * Uninstall tasks.
  33.      * @param UninstallContext $uninstallContext
  34.      */
  35.     public function uninstall(UninstallContext $uninstallContext): void
  36.     {
  37.         parent::uninstall($uninstallContext);
  38.         if ($uninstallContext->keepUserData()) {
  39.             return;
  40.         }
  41.         $this->removeCustomFieldSets($uninstallContext->getContext());
  42.     }
  43.     /**
  44.      * Insert the custom field sets if not already defined.
  45.      * @param Context $context
  46.      */
  47.     private function addCustomFieldSets(Context $context): void
  48.     {
  49.         $customFieldSetRepo $this->container->get('custom_field_set.repository');
  50.         $criteria = (new Criteria())->addFilter(new EqualsFilter('name'self::CUSTOM_FIELDS_SET_CATEGORY));
  51.         if ($customFieldSetRepo->search($criteria$context)->count() === 0) {
  52.             $customFieldSetRepo->create([
  53.                 [
  54.                     'name' => self::CUSTOM_FIELDS_SET_CATEGORY,
  55.                     'position' => 100,
  56.                     'config' => [
  57.                         'label' => [
  58.                             'en-GB' => 'SelfDelve - Category',
  59.                             'de-DE' => 'SelfDelve - Kategorie'
  60.                         ]
  61.                     ],
  62.                     'customFields' => [
  63.                         // Alternative name on category listings
  64.                         [
  65.                             'name' => self::CUSTOM_FIELDS_SET_CATEGORY '_name_alternative',
  66.                             'type' => CustomFieldTypes::TEXT,
  67.                             'config' => [
  68.                                 'label' => [
  69.                                     'en-GB' => 'Alternative Name',
  70.                                     'de-DE' => 'Alternativer Name'
  71.                                 ],
  72.                                 'helpText' => [
  73.                                     'en-GB' => 'Alternative titles of category listings.',
  74.                                     'de-DE' => 'Alternativer Titel auf Kategorielisten.'
  75.                                 ],
  76.                                 'customFieldType' => 'text',
  77.                                 'customFieldPosition' => 10
  78.                             ]
  79.                         ],
  80.                         // Token for categories that are hidden in navigations
  81.                         [
  82.                             'name' => self::CUSTOM_FIELDS_SET_CATEGORY '_access_token',
  83.                             'type' => CustomFieldTypes::TEXT,
  84.                             'config' => [
  85.                                 'label' => [
  86.                                     'en-GB' => 'Access Key',
  87.                                     'de-DE' => 'Zugriffsschlüssel'
  88.                                 ],
  89.                                 'helpText' => [
  90.                                     'en-GB' => 'If a category is hidden in a navigation, this token can hide it completely.',
  91.                                     'de-DE' => 'Wenn eine Kategorie in einer Navigation versteckt ist, kann über diesen Schlüssel ein zusätzlicher Zugriffsschutz hergestellt werden.'
  92.                                 ],
  93.                                 'customFieldType' => 'text',
  94.                                 'customFieldPosition' => 20
  95.                             ]
  96.                         ]
  97.                     ],
  98.                     'relations' => [
  99.                         [
  100.                             'id' => Uuid::randomHex(),
  101.                             'entityName' => CategoryDefinition::ENTITY_NAME
  102.                         ]
  103.                     ]
  104.                 ]
  105.             ], $context);
  106.         }
  107.         $criteria = (new Criteria())->addFilter(new EqualsFilter('name'self::CUSTOM_FIELDS_SET_PRODUCT));
  108.         if ($customFieldSetRepo->search($criteria$context)->count() === 0) {
  109.             $customFieldSetRepo->create([
  110.                 [
  111.                     'name' => self::CUSTOM_FIELDS_SET_PRODUCT,
  112.                     'position' => 200,
  113.                     'config' => [
  114.                         'label' => [
  115.                             'en-GB' => 'SelfDelve - Products',
  116.                             'de-DE' => 'SelfDelve - Produkt'
  117.                         ]
  118.                     ],
  119.                     'customFields' => [
  120.                         // Can be used for top ratings
  121.                         [
  122.                             'name' => self::CUSTOM_FIELDS_SET_PRODUCT '_priority',
  123.                             'type' => CustomFieldTypes::INT,
  124.                             'config' => [
  125.                                 'label' => [
  126.                                     'en-GB' => 'Priority',
  127.                                     'de-DE' => 'Priorität'
  128.                                 ],
  129.                                 'helpText' => [
  130.                                     'en-GB' => 'Can be used for product orderings in groups.',
  131.                                     'de-DE' => 'Kann für Sortierung in Produktgruppen genutzt werden.'
  132.                                 ],
  133.                                 'customFieldType' => 'number',
  134.                                 'customFieldPosition' => 5,
  135.                                 'numberType' => 'int',
  136.                                 'step' => 1,
  137.                                 'min' => 0,
  138.                                 'max' => 10000
  139.                             ]
  140.                         ],
  141.                         // Custom tariffs number for documents
  142.                         [
  143.                             'name' => self::CUSTOM_FIELDS_SET_PRODUCT '_customs_tariff_number',
  144.                             'type' => CustomFieldTypes::TEXT,
  145.                             'config' => [
  146.                                 'label' => [
  147.                                     'en-GB' => 'Custom Tariffs Number',
  148.                                     'de-DE' => 'Zolltarifnummer'
  149.                                 ],
  150.                                 'helpText' => [
  151.                                     'en-GB' => 'Custom tariffs number for documents.',
  152.                                     'de-DE' => 'Zolltarifnummer für den Ausdruck auf Belegen.'
  153.                                 ],
  154.                                 'customFieldType' => 'text',
  155.                                 'customFieldPosition' => 10,
  156.                             ]
  157.                         ],
  158.                         // Highlight a product as custom product
  159.                         [
  160.                             'name' => self::CUSTOM_FIELDS_SET_PRODUCT '_is_custom',
  161.                             'type' => CustomFieldTypes::BOOL,
  162.                             'config' => [
  163.                                 'label' => [
  164.                                     'en-GB' => 'Custom Product',
  165.                                     'de-DE' => 'Sonderanfertigung'
  166.                                 ],
  167.                                 'helpText' => [
  168.                                     'en-GB' => 'Internal mark as custom product.',
  169.                                     'de-DE' => 'Interne Markierung von Sonderanfertigungen.'
  170.                                 ],
  171.                                 'customFieldType' => 'switch',
  172.                                 'componentName' => 'sw-field',
  173.                                 'customFieldPosition' => 20,
  174.                             ]
  175.                         ],
  176.                         // Provision channel
  177.                         [
  178.                             'name' => self::CUSTOM_FIELDS_SET_PRODUCT '_commission',
  179.                             'type' => CustomFieldTypes::SELECT,
  180.                             'config' => [
  181.                                 'label' => [
  182.                                     'en-GB' => 'Provision Channel',
  183.                                     'de-DE' => 'Provisionskanal'
  184.                                 ],
  185.                                 'helpText' => [
  186.                                     'en-GB' => 'Used for sales channel.',
  187.                                     'de-DE' => 'Provisionskanal.'
  188.                                 ],
  189.                                 'customFieldType' => 'select',
  190.                                 'customFieldPosition' => 30,
  191.                                 'componentName' => 'sw-single-select',
  192.                                 'options' => [
  193.                                     [
  194.                                         'value' => 'engel_design',
  195.                                         'label' => [
  196.                                             'en-GB' => 'Engel Design',
  197.                                             'de-DE' => 'Engel Design'
  198.                                         ],
  199.                                     ],
  200.                                     [
  201.                                         'value' => 'hoegl_borowski',
  202.                                         'label' => [
  203.                                             'en-GB' => 'Studio Högl Borowski',
  204.                                             'de-DE' => 'Studio Högl Borowski'
  205.                                         ],
  206.                                     ],
  207.                                     [
  208.                                         'value' => 'sexclusivitaeten',
  209.                                         'label' => [
  210.                                             'en-GB' => 'Sexclusivitäten',
  211.                                             'de-DE' => 'Sexclusivitäten'
  212.                                         ],
  213.                                     ]
  214.                                 ]
  215.                             ]
  216.                         ],
  217.                         // Product-side assignment to product group
  218.                         [
  219.                             'name' => self::CUSTOM_FIELDS_SET_PRODUCT '_dyngroup_manual',
  220.                             'type' => CustomFieldTypes::SELECT,
  221.                             'config' => [
  222.                                 'label' => [
  223.                                     'en-GB' => 'Manual Assignment to Product Group',
  224.                                     'de-DE' => 'Manuelle Zuordnung zu Produktgruppe'
  225.                                 ],
  226.                                 'helpText' => [
  227.                                     'en-GB' => 'Product-side assignment to product group.',
  228.                                     'de-DE' => 'Produktseitige Zuordnung zu einer Produktgruppe (Kriterium kann dort genutzt werden).'
  229.                                 ],
  230.                                 'customFieldType' => 'select',
  231.                                 'customFieldPosition' => 40,
  232.                                 'componentName' => 'sw-single-select',
  233.                                 'options' => [
  234.                                     [
  235.                                         'value' => 'thick',
  236.                                         'label' => [
  237.                                             'en-GB' => 'Thick toys',
  238.                                             'de-DE' => 'Sehr dicke Toys'
  239.                                         ],
  240.                                     ],
  241.                                     [
  242.                                         'value' => 'narrow',
  243.                                         'label' => [
  244.                                             'en-GB' => 'Narrow toys',
  245.                                             'de-DE' => 'Extra schlanke Toys'
  246.                                         ],
  247.                                     ],
  248.                                     [
  249.                                         'value' => 'harness',
  250.                                         'label' => [
  251.                                             'en-GB' => 'Harness toys',
  252.                                             'de-DE' => 'Harnesstaugliche Toys'
  253.                                         ],
  254.                                     ],
  255.                                     [
  256.                                         'value' => 'pimples',
  257.                                         'label' => [
  258.                                             'en-GB' => 'Pimples toys',
  259.                                             'de-DE' => 'Toys mit Noppen'
  260.                                         ],
  261.                                     ],
  262.                                     [
  263.                                         'value' => 'helices',
  264.                                         'label' => [
  265.                                             'en-GB' => 'Helices',
  266.                                             'de-DE' => 'Spiralstrukturen'
  267.                                         ],
  268.                                     ]
  269.                                 ]
  270.                             ]
  271.                         ],
  272.                         // Base body for referencing the configuration product
  273.                         [
  274.                             'name' => self::CUSTOM_FIELDS_SET_PRODUCT '_base_body',
  275.                             'type' => CustomFieldTypes::TEXT,
  276.                             'config' => [
  277.                                 'label' => [
  278.                                     'en-GB' => 'Base Body',
  279.                                     'de-DE' => 'Grundkörper'
  280.                                 ],
  281.                                 'helpText' => [
  282.                                     'en-GB' => 'Base body for referencing the configuration product.',
  283.                                     'de-DE' => 'Wenn dieses Feld ausgefüllt ist, wird auf das Konfigurationsformular verlinkt und das Feld Grundkörper mit diesem Wert gesetzt.'
  284.                                 ],
  285.                                 'customFieldType' => 'text',
  286.                                 'customFieldPosition' => 50,
  287.                             ]
  288.                         ],
  289.                         // Product for canonical entry
  290.                         [
  291.                             'name' => self::CUSTOM_FIELDS_SET_PRODUCT '_canonical_product',
  292.                             'type' => CustomFieldTypes::SELECT,
  293.                             'config' => [
  294.                                 'label' => [
  295.                                     'en-GB' => 'Product for canonical entry',
  296.                                     'de-DE' => 'Produkt für Canonical-Eintrag'
  297.                                 ],
  298.                                 'helpText' => [
  299.                                     'en-GB' => 'Product for canonical entry in meta data.',
  300.                                     'de-DE' => 'Dieses Produkt wird für den Canonical-Eintrag in den Meta-Angaben genutzt.'
  301.                                 ],
  302.                                 'customFieldType' => 'entity',
  303.                                 'customFieldPosition' => 60,
  304.                                 'componentName' => 'sw-entity-single-select',
  305.                                 'entity' => 'product'
  306.                             ]
  307.                         ],
  308.                         // Flag a product as configuration with special templating
  309.                         [
  310.                             'name' => self::CUSTOM_FIELDS_SET_PRODUCT '_is_configurator',
  311.                             'type' => CustomFieldTypes::BOOL,
  312.                             'config' => [
  313.                                 'label' => [
  314.                                     'en-GB' => 'Configurator',
  315.                                     'de-DE' => 'Konfigurator'
  316.                                 ],
  317.                                 'helpText' => [
  318.                                     'en-GB' => 'Product represents a configuration.',
  319.                                     'de-DE' => 'Artikel repräsentiert eine Konfiguration.'
  320.                                 ],
  321.                                 'customFieldType' => 'switch',
  322.                                 'componentName' => 'sw-field',
  323.                                 'customFieldPosition' => 70,
  324.                             ]
  325.                         ],
  326.                         // Configuration header
  327.                         [
  328.                             'name' => self::CUSTOM_FIELDS_SET_PRODUCT '_configuration_listing_header',
  329.                             'type' => CustomFieldTypes::TEXT,
  330.                             'config' => [
  331.                                 'label' => [
  332.                                     'en-GB' => 'Headline of the configurator',
  333.                                     'de-DE' => 'Titel des Konfigurators'
  334.                                 ],
  335.                                 'helpText' => [
  336.                                     'en-GB' => 'Headline in listings.',
  337.                                     'de-DE' => 'Titel des Konfigurator-Banners in Kategorielisten.'
  338.                                 ],
  339.                                 'customFieldType' => 'text',
  340.                                 'customFieldPosition' => 80,
  341.                             ]
  342.                         ],
  343.                         // Configuration text
  344.                         [
  345.                             'name' => self::CUSTOM_FIELDS_SET_PRODUCT '_configuration_listing_text',
  346.                             'type' => CustomFieldTypes::TEXT,
  347.                             'config' => [
  348.                                 'label' => [
  349.                                     'en-GB' => 'Teaser text of the configurator',
  350.                                     'de-DE' => 'Teaser-Text des Konfigurators'
  351.                                 ],
  352.                                 'helpText' => [
  353.                                     'en-GB' => 'Teaser text in listings.',
  354.                                     'de-DE' => 'Teaser-Text des Konfigurator-Banners in Kategorielisten.'
  355.                                 ],
  356.                                 'customFieldType' => 'text',
  357.                                 'customFieldPosition' => 90,
  358.                             ]
  359.                         ],
  360.                         // Configuration button text
  361.                         [
  362.                             'name' => self::CUSTOM_FIELDS_SET_PRODUCT '_configuration_listing_linktext',
  363.                             'type' => CustomFieldTypes::TEXT,
  364.                             'config' => [
  365.                                 'label' => [
  366.                                     'en-GB' => 'Button text of the configurator',
  367.                                     'de-DE' => 'Button-Text des Konfigurators'
  368.                                 ],
  369.                                 'helpText' => [
  370.                                     'en-GB' => 'Button text in listings.',
  371.                                     'de-DE' => 'Button-Text des Konfigurator-Banners in Kategorielisten.'
  372.                                 ],
  373.                                 'customFieldType' => 'text',
  374.                                 'customFieldPosition' => 100,
  375.                             ]
  376.                         ],
  377.                     ],
  378.                     'relations' => [
  379.                         [
  380.                             'id' => Uuid::randomHex(),
  381.                             'entityName' => ProductDefinition::ENTITY_NAME
  382.                         ]
  383.                     ]
  384.                 ]
  385.             ], $context );
  386.         }
  387.         $criteria = (new Criteria())->addFilter(new EqualsFilter('name'self::CUSTOM_FIELDS_SET_SHIPPING_METHOD));
  388.         if ($customFieldSetRepo->search($criteria$context)->count() === 0) {
  389.             $customFieldSetRepo->create([
  390.                 [
  391.                     'name' => self::CUSTOM_FIELDS_SET_SHIPPING_METHOD,
  392.                     'position' => 300,
  393.                     'config' => [
  394.                         'label' => [
  395.                             'en-GB' => 'SelfDelve - Shipping Methods',
  396.                             'de-DE' => 'SelfDelve - Versandarten'
  397.                         ]
  398.                     ],
  399.                     'customFields' => [
  400.                         // Force phone number on method selection
  401.                         [
  402.                             'name' => self::CUSTOM_FIELDS_SET_SHIPPING_METHOD '_mandatory_phonenumber',
  403.                             'type' => CustomFieldTypes::BOOL,
  404.                             'config' => [
  405.                                 'label' => [
  406.                                     'en-GB' => 'Phone number is mandatory',
  407.                                     'de-DE' => 'Telefonnummer muss angegeben werden'
  408.                                 ],
  409.                                 'customFieldType' => 'switch',
  410.                                 'componentName' => 'sw-field',
  411.                                 'customFieldPosition' => 0
  412.                             ]
  413.                         ]
  414.                     ],
  415.                     'relations' => [
  416.                         [
  417.                             'id' => Uuid::randomHex(),
  418.                             'entityName' => ShippingMethodDefinition::ENTITY_NAME
  419.                         ]
  420.                     ]
  421.                 ]
  422.             ], $context);
  423.         }
  424.         $criteria = (new Criteria())->addFilter(new EqualsFilter('name'self::CUSTOM_FIELD_SET_COUNTRY));
  425.         if ($customFieldSetRepo->search($criteria$context)->count() === 0) {
  426.             $customFieldSetRepo->create([
  427.                 [
  428.                     'name' => self::CUSTOM_FIELDS_SET_CATEGORY,
  429.                     'position' => 100,
  430.                     'config' => [
  431.                         'label' => [
  432.                             'en-GB' => 'SelfDelve - Countries',
  433.                             'de-DE' => 'SelfDelve - Länder'
  434.                         ]
  435.                     ],
  436.                     'customFields' => [
  437.                         [
  438.                             'name' => self::CUSTOM_FIELD_SET_COUNTRY '_has_customs_surcharge',
  439.                             'type' => CustomFieldTypes::BOOL,
  440.                             'config' => [
  441.                                 'label' => [
  442.                                     'en-GB' => 'Has customs surcharge',
  443.                                     'de-DE' => 'Hat Zoll-Aufschlag'
  444.                                 ],
  445.                                 'customFieldPosition' => 10
  446.                             ]
  447.                         ],
  448.                         [
  449.                             'name' => self::CUSTOM_FIELD_SET_COUNTRY '_customs_surcharge',
  450.                             'type' => CustomFieldTypes::FLOAT,
  451.                             'config' => [
  452.                                 'label' => [
  453.                                     'en-GB' => 'Surcharge (%)',
  454.                                     'de-DE' => 'Prozentualer Aufschlag'
  455.                                 ],
  456.                                 'customFieldPosition' => 20
  457.                             ]
  458.                         ],
  459.                         [
  460.                             'name' => self::CUSTOM_FIELD_SET_COUNTRY '_customs_surcharge_label',
  461.                             'type' => CustomFieldTypes::TEXT,
  462.                             'config' => [
  463.                                 'label' => [
  464.                                     'en-GB' => 'Surcharge label',
  465.                                     'de-DE' => 'Bezeichnung der Aufschlagsposition'
  466.                                 ],
  467.                                 'customFieldPosition' => 30
  468.                             ]
  469.                         ],
  470.                     ],
  471.                     'relations' => [
  472.                         [
  473.                             'id' => Uuid::randomHex(),
  474.                             'entityName' => CountryDefinition::ENTITY_NAME
  475.                         ]
  476.                     ]
  477.                 ]
  478.             ], $context);
  479.         }
  480.     }
  481.     /**
  482.      * Remove the custom field sets.
  483.      * @param Context $context
  484.      */
  485.     private function removeCustomFieldSets(Context $context): void
  486.     {
  487.         $customFieldSetRepo $this->container->get('custom_field_set.repository');
  488.         $setNames = [
  489.             self::CUSTOM_FIELDS_SET_CATEGORY,
  490.             self::CUSTOM_FIELDS_SET_CUSTOMER,
  491.             self::CUSTOM_FIELDS_SET_PRODUCT
  492.         ];
  493.         foreach ($setNames as $setName) {
  494.             $id $customFieldSetRepo->searchIds((new Criteria())->addFilter(new EqualsFilter('name'$setName)), $context)->firstId();
  495.             if ($id) {
  496.                 $customFieldSetRepo->delete([
  497.                     ['id' => $id]
  498.                 ], $context);
  499.             }
  500.         }
  501.     }
  502. }