【问题标题】:Custom code format for specified code in PhpStormPhpStorm 中指定代码的自定义代码格式
【发布时间】:2019-03-19 23:39:13
【问题描述】:

使用“with”的 Sonata Admin 的 PHP 代码由自动格式化程序格式化,如下所示:

$formMapper->with('User')
           ->add('firstName')
           ->add('lastName')
           ->end()
           ->with('Additional Information')
           ->add('gender')
           ->end()

为了获得更易于阅读的代码样式,我目前禁用并启用格式化程序并将代码格式化如下:

// @formatter:off
$formMapper
    ->with('User')
        ->add('firstName')
        ->add('lastName')
    ->end()
    ->with('Additional Information')
        ->add('gender')
    ->end()
;
// @formatter:on

有没有办法为特定的代码短语定义代码样式?例如使用正则表达式将代码自动格式化为第二种样式?

【问题讨论】:

  • 你必须编写一个自定义插件,不幸的是 Intellij 没有内置这个功能。

标签: phpstorm sonata-admin jetbrains-ide formatter


【解决方案1】:

我刚刚通过扩展 php 代码使其“可自动格式化”,找到了一个特别适用于奏鸣曲管理案例的解决方案。这是我所做的:

ObjectTypeCaster.php(来自https://stackoverflow.com/a/53081037/301277):

class ObjectTypeCaster
{
    /**
     * This method is able to recast an object by copying all properties
     */
    public static function castAs($sourceObject, $newClass)
    {
        $castedObject                    = new $newClass();
        $reflectedSourceObject           = new \ReflectionClass($sourceObject);
        $reflectedSourceObjectProperties = $reflectedSourceObject->getProperties();

        foreach ($reflectedSourceObjectProperties as $reflectedSourceObjectProperty) {
            $propertyName = $reflectedSourceObjectProperty->getName();

            $reflectedSourceObjectProperty->setAccessible(true);

            $castedObject->$propertyName = $reflectedSourceObjectProperty->getValue($sourceObject);
        }

        return $castedObject;
    }
}

像这样扩展FormMapperShowMapper

IndentedFormMapper.php:

<?php

namespace App\Admin\Form;

use App\Helper\ObjectTypeCaster;
use Sonata\AdminBundle\Admin\AdminInterface;
use Sonata\AdminBundle\Builder\BuilderInterface;
use Sonata\AdminBundle\Builder\FormContractorInterface;
use Sonata\AdminBundle\Form\FormMapper;
use Symfony\Component\Form\FormBuilderInterface;

class IndentedFormMapper extends FormMapper
{
    /**
     * Makes protected property from BaseMapper public
     *
     * @var AdminInterface
     */
    public $admin;

    /**
     * Makes protected property from BaseMapper public
     *
     * @var BuilderInterface
     */
    public $builder;

    /**
     * Makes protected property from FormMapper public
     *
     * @var FormBuilderInterface
     */
    public $formBuilder;

    /**
     * Makes protected property from BaseGroupedMapper public
     *
     * @var string|null
     */
    public $currentGroup;

    /**
     * Makes protected property from BaseGroupedMapper public
     *
     * @var string|null
     */
    public $currentTab;

    /**
     * Makes protected property from BaseGroupedMapper public
     *
     * @var bool|null
     */
    public $apply;

    /**
     * We overwrite the constructor from FormMapper and BaseMapper to be able to create
     * this object without any parameter. Its properties are copied by ObjectTypeCaster.
     *
     * IndentedFormMapper constructor.
     *
     * @see ObjectTypeCaster
     */
    public function __construct()
    {

    }

    /**
     * This makes it possible to chain this object in a way that allows
     * autoformatting in IntelliJ IDEs. Usage:
     *
     * $formMapper
     *     ->tab('General')
     *     ->chain(function ($formMapper) {
     *         $formMapper
     *             ->add('...')
     *             // Default usage here, you can also chain again
     *         ;
     *     })
     *     ->end()
     * ;
     *
     * @param $callback
     * @return $this
     */
    public function chain($callback)
    {
        $callback($this);

        return $this;
    }
}

IndentedShowMapper.php:

<?php

namespace App\Admin\Form;

use App\Helper\ObjectTypeCaster;
use Sonata\AdminBundle\Admin\AdminInterface;
use Sonata\AdminBundle\Builder\BuilderInterface;
use Sonata\AdminBundle\Builder\FormContractorInterface;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Symfony\Component\Form\FormBuilderInterface;

class IndentedShowMapper extends ShowMapper
{
    /**
     * Makes protected property from ShowMapper public
     *
     * @var AdminInterface
     */
    public $list;

    /**
     * Makes protected property from BaseGroupedMapper public
     *
     * @var string|null
     */
    public $currentGroup;

    /**
     * Makes protected property from BaseGroupedMapper public
     *
     * @var string|null
     */
    public $currentTab;

    /**
     * Makes protected property from BaseGroupedMapper public
     *
     * @var bool|null
     */
    public $apply;

    /**
     * Makes protected property from BaseMapper public
     *
     * @var AdminInterface
     */
    public $admin;

    /**
     * Makes protected property from BaseMapper public
     *
     * @var BuilderInterface
     */
    public $builder;

    /**
     * We overwrite the constructor from ShowMapper and BaseMapper to be able to create
     * this object without any parameter. Its properties are copied by ObjectTypeCaster.
     *
     * IndentedFormMapper constructor.
     *
     * @see ObjectTypeCaster
     */
    public function __construct()
    {

    }

    /**
     * This makes it possible to chain this object in a way that allows
     * autoformatting in IntelliJ IDEs. Usage:
     *
     * $showMapper
     *     ->tab('General')
     *     ->chain(function ($showMapper) {
     *         $showMapper
     *             ->add('...')
     *             // Default usage here, you can also chain again
     *         ;
     *     })
     *     ->end()
     * ;
     *
     * @param $callback
     * @return $this
     */
    public function chain($callback)
    {
        $callback($this);

        return $this;
    }
}

添加一个您在所有管理类中继承的 BaseAdmin 类并添加以下方法:

<?php

use App\Admin\Form\IndentedFormMapper;
use App\Admin\Form\IndentedShowMapper;
use App\Entity\User;
use App\Helper\ObjectTypeCaster;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Mapper\BaseMapper;
use Sonata\AdminBundle\Show\ShowMapper;

class BaseAdmin extends AbstractAdmin
{

    /**
     * @param FormMapper $formMapper
     * @throws \ReflectionException
     */
    protected function configureFormFields(FormMapper $formMapper)
    {
        $indentFormMapper = ObjectTypeCaster::castAs($formMapper, IndentedFormMapper::class);

        $this->configureFormFieldsIndention($indentFormMapper);
    }

    /**
     * @param IndentedFormMapper $formMapper
     */
    protected function configureFormFieldsIndention(IndentedFormMapper $formMapper)
    {

    }

    /**
     * @param ShowMapper $showMapper
     * @throws \ReflectionException
     */
    protected function configureShowFields(ShowMapper $showMapper)
    {
        $indentShowMapper = ObjectTypeCaster::castAs($showMapper, IndentedShowMapper::class);

        $this->configureShowFieldsIndention($indentShowMapper);
    }

    /**
     * @param IndentedShowMapper $showMapper
     */
    protected function configureShowFieldsIndention(IndentedShowMapper $showMapper)
    {

    }
}

在您的 BaseAdmin 子类中使用它,如下所示:

ExampleAdmin.php:

<?php

namespace App\Admin;

use App\Admin\Form\IndentedFormMapper;
use App\Admin\Form\IndentedShowMapper;
use App\Entity\Example;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;

class ExampleAdmin extends BaseAdmin
{
    // ...

    /**
     * @param IndentedFormMapper $formMapper
     */
    protected function configureFormFieldsIndention(IndentedFormMapper $formMapper)
    {
        $formMapper
            ->tab('General')
            ->chain(function ($formMapper) {
                $formMapper
                    ->with(
                        'Example',
                        [
                            'class' => AdminLayout::HALF,
                        ]
                    )
                    ->chain(function ($formMapper) {
                        $formMapper
                            ->add(
                                'name',
                                Types::TEXT
                            )
                        ;
                    })
                    ->end()
                ;
            })
            ->end()
        ;
    }

    /**
     * @param IndentedShowMapper $showMapper
     */
    protected function configureShowFieldsIndention(IndentedShowMapper $showMapper)
    {
        $mapData = $this->getMapData();

        $showMapper
            ->with('Internal')
            ->chain(function ($showMapper) {
                $showMapper
                    ->add('id')
                    ->add('createdAt')
                    ->add('updatedAt')
                ;
            })
            ->end()
        ;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多