Haehnchen / idea-php-shopware-plugin

Shopware Plugin for PhpStorm which extends Symfony Plugin
MIT License
53 stars 9 forks source link

support for Extract-Feature #80

Open FalkoHilbert opened 5 years ago

FalkoHilbert commented 5 years ago

It would be nice when this Plugin has a Support for the PHPStorm Extract Feature to automatic creation of config-fields in config.xml if it is a Shopware 5.2 plugin structure. Idea Example:

  1. Write some Plugin-Code with some string constants
  2. mark the string and click right mouse button
  3. under Refactor->Extract add entry to generate shopware-config-field
  4. add a xml-node in config.xml (if not exist create config.xml) with
        <element>
            <name>[STRING]</name>
            <label lang="de">[STRING]</label>
            <label>[STRING]</label>
        </element>

    Additionally should the PHPStorm-Plugin have an Config-Parameter to define a prefix of plugins to force the prefixing of plugin-names and plugin-config fields. Alternatively, one could also read the prefix for the config fields from the name of the plugin. This idea could save time when refactoring plugin-code.

cedricziel commented 5 years ago

Can you provide some concrete example with before and after snippets?

FalkoHilbert commented 5 years ago

okay, here a "simple" example

Before: Subscriber:

<?php

namespace FHMyPlugin\Subscriber;

use Doctrine\DBAL\Connection;
use Enlight\Event\SubscriberInterface;
use PDO;

class Frontend implements SubscriberInterface
{
    /**
     * @var Connection
     */
    private $connection;

    /**
     * Frontend constructor.
     * @param Connection $connection
     */
    function __construct(
        Connection $connection
    )
    {
        $this->connection = $connection;
    }

    public static function getSubscribedEvents()
    {
        return array(
            'Enlight_Controller_Action_PostDispatchSecure_Frontend' => 'onFrontendPostDispatch'
        );
    }

    public function onFrontendPostDispatch(\Enlight_Event_EventArgs $args)
    {
        /** @var $controller \Enlight_Controller_Action */
        $controller = $args->getSubject();
        $view = $controller->View();

        $qb = $this->connection->createQueryBuilder();
        $qb->select('ac.articleID')
           ->from('s_articles_categories', 'ac')
           ->where('ac.categoryID = :catId' )
           ->setParameter('catId', 1 );

        $articles = $qb->execute()->fetchAll(PDO::FETCH_COLUMN);

        $view->assign('specialArticles', $articles);
        $view->assign('specialArticlesText', 'my Special Text');
    }
}

services.xml:

<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    <services>
        <service class="FHMyPlugin\Subscriber\Frontend" id="fhmy_plugin.subscriber.frontend">
            <argument id="dbal_connection" type="service"/>
            <tag name="shopware.event_subscriber"/>
        </service>
    </services>
</container>

config.xml:

<?xml version="1.0" encoding="utf-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:noNamespaceSchemaLocation="../../../../engine/Shopware/Components/Plugin/schema/config.xsd">
    <elements>
        <element type="text">
            <name>demoConfig</name>
            <label lang="de">Demo Konfiguration</label>
            <label lang="en">Demo configuration</label>
            <value>Just a demo configuration, without any effects.</value>
        </element>
    </elements>
</config>

when i refactor this code i will see, that there is a fixed interger Value at the category Parameter and a fixed string as view parameter. so, now i would like to generate config-fields to give the customer the oppportunity to decide which category and which text should use.

After:

<?php

namespace FHMyPlugin\Subscriber;

use Doctrine\DBAL\Connection;
use Enlight\Event\SubscriberInterface;
use PDO;
use Shopware\Components\Plugin\ConfigReader;

class Frontend implements SubscriberInterface
{
    /**
     * @var Connection
     */
    private $connection;
    /**
     * @var array
     */
    private $config;

    /**
     * Frontend constructor.
     * @param Connection $connection
     * @param ConfigReader $configReader
     */
    function __construct(
        Connection $connection,
        ConfigReader $configReader
    )
    {
        $this->connection = $connection;
        $this->config = $configReader->getByPluginName('FHMyPlugin');
    }

    public static function getSubscribedEvents()
    {
        return array(
            'Enlight_Controller_Action_PostDispatchSecure_Frontend' => 'onFrontendPostDispatch'
        );
    }

    public function onFrontendPostDispatch(\Enlight_Event_EventArgs $args)
    {
        /** @var $controller \Enlight_Controller_Action */
        $controller = $args->getSubject();
        $view = $controller->View();

        $qb = $this->connection->createQueryBuilder();
        $qb->select('ac.articleID')
           ->from('s_articles_categories', 'ac')
           ->where('ac.categoryID = :catId' )
           ->setParameter('catId', $this->config['FH_1'] );

        $articles = $qb->execute()->fetchAll(PDO::FETCH_COLUMN);

        $view->assign('specialArticles', $articles);
        $view->assign('specialArticlesText', $this->config['FH_MY_SPECIAL_TEXT']);
    }
}

services.xml, when the php class is an existing symfony service:

<?xml version="1.0" encoding="utf-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    <services>
        <service class="FHMyPlugin\Subscriber\Frontend" id="fhmy_plugin.subscriber.frontend">
            <argument id="dbal_connection" type="service"/>
            <argument type="service" id="shopware.plugin.config_reader"/>
            <tag name="shopware.event_subscriber"/>
        </service>
    </services>
</container>

config.xml:

<?xml version="1.0" encoding="utf-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="../../../../engine/Shopware/Components/Plugin/schema/config.xsd">
    <elements>
        <element type="text">
            <name>demoConfig</name>
            <label lang="de">Demo Konfiguration</label>
            <label lang="en">Demo configuration</label>
            <value>Just a demo configuration, without any effects.</value>
        </element>
        <element type="text">
            <name>FH_1</name>
            <label lang="de">FH_1</label>
            <label lang="en">FH_1</label>
            <value>1</value>
        </element>
        <element type="text">
            <name>FH_MY_SPECIAL_TEXT</name>
            <label lang="de">FH_MY_SPECIAL_TEXT</label>
            <label lang="en">FH_MY_SPECIAL_TEXT</label>
            <value>my Special Text</value>
        </element>
    </elements>
</config>

Ideally, the "extract" step can independently determine a more appropriate name and label for the config-field based on the function, variable, or simular before the value to be extracted.

example: Before: Subscriber:

<?php
        [...]
           ->setParameter('catId', 1 );
        [...]
        $view->assign('specialArticlesText', 'my Special Text');

After: config.xml:

<?xml version="1.0" encoding="utf-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="../../../../engine/Shopware/Components/Plugin/schema/config.xsd">
    <elements>
        [...]
        <element type="text">
            <name>FH_CAT_ID</name>
            <label lang="de">catId</label>
            <label lang="en">catId</label>
            <value>1</value>
        </element>
        <element type="text">
            <name>FH_SPECIAL_ARTICLE_TEXT</name>
            <label lang="de">specialArticlesText</label>
            <label lang="en">specialArticlesText</label>
            <value>my Special Text</value>
        </element>
    </elements>
</config>
cedricziel commented 5 years ago

So it's essentially these steps:

FalkoHilbert commented 5 years ago

That's right

FalkoHilbert commented 5 years ago

Hi @Haehnchen, @cedricziel,

Is there any news?