PhpStorm - 设置制定者和吸气剂

时间:2016-04-25 12:00:48

标签: phpstorm

PhpStorm在快速创建setter和getter时有一个很有用的功能:

Code -> generate -> select the items to generate 

这非常适合设置基本的setter / getter。

然而,我不时想要设置的不仅仅是设置者和吸气剂。例如,我可能想要为一对多或多对多关系创建setter和getter。

即。

多对多

/**
 * {@inheritDoc}
 */
public function getOwner()
{
    return $this->owner->toArray();
}

/**
 * Set the list of user
 * @param Collection $owner
 */
public function setOwner( Collection $owner )
{
    $this->registeredUsers->clear();

    foreach ( $owner as $item ) {
        $this->owner[] = $item;
    }
}

/**
 * Add merchant to the collection
 * @param Collection $owner
 */
public function addOwner( Collection $owner )
{
    foreach( $owner as $item ) {
        $this->owner->add( $item );
    }
}

/**
 * @param Collection $owner
 */
public function removeOwner( Collection $owner )
{
    foreach( $owner as $item ) {
        $this->owner->removeElement( $item );
    }
}

有没有办法通过相同的代码生成过程来做到这一点?

2 个答案:

答案 0 :(得分:2)

不幸的是,ATM PhpStorm不支持​​此类功能。

https://youtrack.jetbrains.com/issue/WI-25003 - 观看此门票(明星/投票/评论)以获得有关任何进展的通知(到目前为止,未计划任何特定的未来版本 - 可能是因为票数非常低 - 排序of:no votes = no interest =不需要立即投入资源)。

相关:https://youtrack.jetbrains.com/issue/WI-19891

我现在能想到的唯一选择(将使用代码生成功能)..是修改Getter / Setter的模板,以便它包含多个方法(example)。这样您就可以一次性生成setXXX / addXXX以及getXXX / removeXXX方法。

显然,它会在所有情况下都适用,所以如果你只需要get/set,那么你需要手动删除add/remove方法 - 这就是这种方法的缺点。

请注意文件&代码模板可以是IDE范围(Default模式)或项目特定的(Project模式)..因此您可以仅在某些项目中使用此类组合的getter / setter。

https://www.jetbrains.com/help/phpstorm/2016.1/file-and-code-templates-2.html

唯一的另一种选择是半手动并要求您使用Live Templates

  • 制作实际的实时模板(一次性工作)
  • 您需要手动查找要放置此代码的位置
  • 调用实时模板扩展(以便插入代码模板)
  • 填写所有实时模板变量以完成代码。

使用您的addXXX / removeXXX代码示例,可能最终只填充1或2个模板变量(只是对我看到的内容进行快速估算;相同的变量可以多次使用,因此可以在几个地方同时填充;输入的文本可以转换(有限的转换集),因此可以自动在另一个变量中重复使用(例如,您正在键入owner和在另一个地方,它会自动用作Owner

答案 1 :(得分:0)

检查出来:

#set ($array = $TYPE_HINT.split('\|'));
#set ($IS_COLLECTION = false);
#set ($FIXED_RETURN_TYPE = $RETURN_TYPE);
#set ($NAME_LENGTH = $FIELD_NAME.length());
#set ($NAME_BEFORE_LAST = $FIELD_NAME.length() - 1);
#set ($LAST_CHARACTER = $FIELD_NAME.substring($NAME_BEFORE_LAST, $NAME_LENGTH));
#set ($METHOD_NAME_BEFORE_LAST = $NAME.length() - 1);

#if (${LAST_CHARACTER} == 's')
    #set ($FIXED_PROPERTY_NAME = $FIELD_NAME.substring(0, $NAME_BEFORE_LAST));
    #set ($FIXED_METHOD_NAMING_PART = $NAME.substring(0, $METHOD_NAME_BEFORE_LAST));
#else
    #set ($FIXED_PROPERTY_NAME = $FIELD_NAME);
    #set ($FIXED_METHOD_NAMING_PART = $NAME);
#end

#foreach($hint in $array)
    #if ($hint.toString().contains('[]'))
        #set ($ENTRY_HINT = $hint.toString().replace('[]', ''));
        #set ($HAS_ENTRY_HINT = true);
    #end
#end

#foreach($hint in $array)
    #if ($hint == 'Collection')
        #set ($IS_COLLECTION = true)
        #set ($FIXED_RETURN_TYPE = 'Collection')
        #break
    #elseif ($hint == 'ArrayCollection')
        #set ($IS_COLLECTION = true)
        #set ($FIXED_RETURN_TYPE = 'Collection')
        #break
    #elseif ($hint == 'array')
        #set ($IS_COLLECTION = true)
        #set ($FIXED_RETURN_TYPE = 'array')
    #elseif ($hint.toString().contains('[]'))
        #set ($IS_COLLECTION = true)
        #set ($FIXED_RETURN_TYPE = 'array')
    #end
#end

#if ($IS_COLLECTION)
/**
 * @param ${ENTRY_HINT} $${FIXED_PROPERTY_NAME}
 *
 * @return ${CLASS_NAME}
 */
public function add${FIXED_METHOD_NAMING_PART}(#if (${HAS_ENTRY_HINT})${ENTRY_HINT} #else#end$${FIXED_PROPERTY_NAME})#if(${RETURN_TYPE}): ${CLASS_NAME}#else#end
{
#if ($FIXED_RETURN_TYPE == 'Collection')
    if(false === $this->${FIELD_NAME}->contains($${FIXED_PROPERTY_NAME})) {
        $this->${FIELD_NAME}->add($${FIXED_PROPERTY_NAME});
    }
#else
    if(false === in_array($${FIXED_PROPERTY_NAME}, $this->${FIELD_NAME}, true)) {
        $this->${FIELD_NAME}[] = $${FIXED_PROPERTY_NAME};
    }
#end

    return $this;
}

/**
 * @param ${ENTRY_HINT} $${FIXED_PROPERTY_NAME}
 *
 * @return ${CLASS_NAME}
 */
public function remove${FIXED_METHOD_NAMING_PART}(#if (${HAS_ENTRY_HINT})${ENTRY_HINT} #else#end$${FIXED_PROPERTY_NAME})#if(${RETURN_TYPE}): ${CLASS_NAME}#else#end
{
#if ($FIXED_RETURN_TYPE == 'Collection')
    if(true === $this->${FIELD_NAME}->contains($${FIXED_PROPERTY_NAME})) {
        $this->${FIELD_NAME}->removeElement($${FIXED_PROPERTY_NAME});
    }
#else
    if(true === in_array($${FIXED_PROPERTY_NAME}, $this->${FIELD_NAME}, true)) {
        $index = array_search($${FIXED_PROPERTY_NAME}, $this->${FIELD_NAME});
        array_splice($this->${FIELD_NAME}, $index, 1);
    }
#end

    return $this;
}
#end
/**
 * @param ${TYPE_HINT} $${PARAM_NAME}
 * @return ${CLASS_NAME}
 */
public function set${NAME}(#if (${SCALAR_TYPE_HINT})${SCALAR_TYPE_HINT} #else#end$${PARAM_NAME})#if(${RETURN_TYPE}): ${CLASS_NAME}#else#end
{
    $this->${FIELD_NAME} = $${PARAM_NAME};
    return $this;
}

我设法创造了类似的东西,随时根据您的需求进行修改。这是流畅的setter 实时模板。

它适用于Doctrine的Collection / ArrayCollection数组。扩展此功能就像创建新的 #elseif 语句一样简单。

/**
 * @var array|string[]
 */
protected $oneField;

/**
 * @var ArrayCollection|Collection|Another[]
 *
 * @ORM\OneToMany(targetEntity="Acme\DemoBundle\Entity\Another")
 */
protected $anotherField;