<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Mr Miao</title>
  
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="http://yoursite.com/"/>
  <updated>2016-10-15T12:43:27.000Z</updated>
  <id>http://yoursite.com/</id>
  
  <author>
    <name>miaotaizi</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>FOSUserBundle的分组功能</title>
    <link href="http://yoursite.com/2016/10/15/fosuserbundle-groups/"/>
    <id>http://yoursite.com/2016/10/15/fosuserbundle-groups/</id>
    <published>2016-10-15T12:37:16.000Z</published>
    <updated>2016-10-15T12:43:27.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>原文地址<a href="http://symfony.com/doc/current/bundles/FOSUserBundle/groups.html" target="_blank" rel="noopener">http://symfony.com/doc/current/bundles/FOSUserBundle/groups.html</a></p></blockquote><p>FOSUserBundle允许你对用户进行分组. 分组是区分角色集合的一种方式. 一个组里面的用户会被授予这个组里面所有角色的权限.</p><blockquote><p>Symfony支持角色继承, 所以从组中继承角色不是必须的. 如果在你的使用场景中继承了足够多的角色, 最好还是使用继承, 因为它更为高效.(分组功能需要数据库的驱动.)</p></blockquote><p>你需要在配置文件中明确启用这个启用分组功能. 唯一强制性的就是要配置你实现了<code>FOS\UserBundle\Model\GroupInterface</code>接口的<code>Group</code>类的完全限定名(fully qualified class name).</p><a id="more"></a><p>下面是一个支持分组功能的配置例子:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"># app/config/config.yml</span><br><span class="line">fos_user:</span><br><span class="line">    db_driver: orm</span><br><span class="line">    firewall_name: main</span><br><span class="line">    user_class: AppBundle\Entity\User</span><br><span class="line">    group:</span><br><span class="line">        group_class: AppBundle\Entity\Group</span><br></pre></td></tr></table></figure><h4 id="分组类"><a href="#分组类" class="headerlink" title="分组类"></a>分组类</h4><p>创建分组类的最简单的方式就是去继承FOSUserBundle提供的映射过的超类.</p><h5 id="ORM-分组类的实现"><a href="#ORM-分组类的实现" class="headerlink" title="ORM 分组类的实现"></a>ORM 分组类的实现</h5><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// src/AppBundle/Entity/Group.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">AppBundle</span>\<span class="title">Entity</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">FOS</span>\<span class="title">UserBundle</span>\<span class="title">Model</span>\<span class="title">Group</span> <span class="title">as</span> <span class="title">BaseGroup</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">Doctrine</span>\<span class="title">ORM</span>\<span class="title">Mapping</span> <span class="title">as</span> <span class="title">ORM</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ORM</span>\Entity</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ORM</span>\Table(name="fos_group")</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Group</span> <span class="keyword">extends</span> <span class="title">BaseGroup</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ORM</span>\Id</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ORM</span>\Column(type="integer")</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ORM</span>\GeneratedValue(strategy="AUTO")</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">     <span class="keyword">protected</span> $id;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><blockquote><p>因为<code>Group</code>是SQL中的一个保留的关键字, 所以它不能用于表名.</p></blockquote><h5 id="MongoDB-分组类的实现"><a href="#MongoDB-分组类的实现" class="headerlink" title="MongoDB 分组类的实现"></a>MongoDB 分组类的实现</h5><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// src/AppBundle/Document/Group.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">AppBundle</span>\<span class="title">Document</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">FOS</span>\<span class="title">UserBundle</span>\<span class="title">Model</span>\<span class="title">Group</span> <span class="title">as</span> <span class="title">BaseGroup</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">Doctrine</span>\<span class="title">ODM</span>\<span class="title">MongoDB</span>\<span class="title">Mapping</span>\<span class="title">Annotations</span> <span class="title">as</span> <span class="title">MongoDB</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@MongoDB</span>\Document</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Group</span> <span class="keyword">extends</span> <span class="title">BaseGroup</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@MongoDB</span>\Id(strategy="auto")</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">protected</span> $id;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h5 id="CouchDB-分组类的实现"><a href="#CouchDB-分组类的实现" class="headerlink" title="CouchDB 分组类的实现"></a>CouchDB 分组类的实现</h5><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// src/AppBundle/CouchDocument/Group.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">AppBundle</span>\<span class="title">CouchDocument</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">FOS</span>\<span class="title">UserBundle</span>\<span class="title">Model</span>\<span class="title">Group</span> <span class="title">as</span> <span class="title">BaseGroup</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">Doctrine</span>\<span class="title">ODM</span>\<span class="title">CouchDB</span>\<span class="title">Mapping</span>\<span class="title">Annotations</span> <span class="title">as</span> <span class="title">CouchDB</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@CouchDB</span>\Document</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Group</span> <span class="keyword">extends</span> <span class="title">BaseGroup</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@CouchDB</span>\Id</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">protected</span> $id;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="定义用户与分组的关系"><a href="#定义用户与分组的关系" class="headerlink" title="定义用户与分组的关系"></a>定义用户与分组的关系</h4><p>下一步就是在你的<code>User</code>类中进行关系映射</p><h5 id="ORM用户-分组映射"><a href="#ORM用户-分组映射" class="headerlink" title="ORM用户-分组映射"></a>ORM用户-分组映射</h5><p>Annotations 配置方式</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// src/AppBundle/Entity/User.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">AppBundle</span>\<span class="title">Entity</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">FOS</span>\<span class="title">UserBundle</span>\<span class="title">Model</span>\<span class="title">User</span> <span class="title">as</span> <span class="title">BaseUser</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ORM</span>\Entity</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ORM</span>\Table(name="fos_user")</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">User</span> <span class="keyword">extends</span> <span class="title">BaseUser</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ORM</span>\Id</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ORM</span>\Column(type="integer")</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ORM</span>\GeneratedValue(strategy="AUTO")</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">protected</span> $id;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ORM</span>\ManyToMany(targetEntity="AppBundle\Entity\Group")</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ORM</span>\JoinTable(name="fos_user_user_group",</span></span><br><span class="line"><span class="comment">     *      joinColumns=&#123;<span class="doctag">@ORM</span>\JoinColumn(name="user_id", referencedColumnName="id")&#125;,</span></span><br><span class="line"><span class="comment">     *      inverseJoinColumns=&#123;<span class="doctag">@ORM</span>\JoinColumn(name="group_id", referencedColumnName="id")&#125;</span></span><br><span class="line"><span class="comment">     * )</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">protected</span> $groups;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>YAML配置方式</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"># src/AppBundle/Resources/config/doctrine/User.orm.yml</span><br><span class="line">AppBundle\Entity\User:</span><br><span class="line">    type:  entity</span><br><span class="line">    table: fos_user</span><br><span class="line">    id:</span><br><span class="line">        id:</span><br><span class="line">            type: integer</span><br><span class="line">            generator:</span><br><span class="line">                strategy: AUTO</span><br><span class="line">    manyToMany:</span><br><span class="line">        groups:</span><br><span class="line">            targetEntity: Group</span><br><span class="line">            joinTable:</span><br><span class="line">                name: fos_user_group</span><br><span class="line">                joinColumns:</span><br><span class="line">                    user_id:</span><br><span class="line">                        referencedColumnName: id</span><br><span class="line">                inverseJoinColumns:</span><br><span class="line">                    group_id:</span><br><span class="line">                        referencedColumnName: id</span><br></pre></td></tr></table></figure><h5 id="MongoDB用户-分组映射"><a href="#MongoDB用户-分组映射" class="headerlink" title="MongoDB用户-分组映射"></a>MongoDB用户-分组映射</h5><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// src/AppBundle/Document/User.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">AppBundle</span>\<span class="title">Document</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">FOS</span>\<span class="title">UserBundle</span>\<span class="title">Model</span>\<span class="title">User</span> <span class="title">as</span> <span class="title">BaseUser</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">Doctrine</span>\<span class="title">ODM</span>\<span class="title">MongoDB</span>\<span class="title">Mapping</span>\<span class="title">Annotations</span> <span class="title">as</span> <span class="title">MongoDB</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@MongoDB</span>\Document</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">User</span> <span class="keyword">extends</span> <span class="title">BaseUser</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">/** <span class="doctag">@MongoDB</span>\Id(strategy="auto") */</span></span><br><span class="line">    <span class="keyword">protected</span> $id;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@MongoDB</span>\ReferenceMany(targetDocument="AppBundle\Document\Group")</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">protected</span> $groups;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h5 id="CouchDB用户-分组映射"><a href="#CouchDB用户-分组映射" class="headerlink" title="CouchDB用户-分组映射"></a>CouchDB用户-分组映射</h5><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// src/AppBundle/CouchDocument/User.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">AppBundle</span>\<span class="title">CouchDocument</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">FOS</span>\<span class="title">UserBundle</span>\<span class="title">Model</span>\<span class="title">User</span> <span class="title">as</span> <span class="title">BaseUser</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">Doctrine</span>\<span class="title">ODM</span>\<span class="title">CouchDB</span>\<span class="title">Mapping</span>\<span class="title">Annotations</span> <span class="title">as</span> <span class="title">CouchDB</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@CouchDB</span>\Document</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">User</span> <span class="keyword">extends</span> <span class="title">BaseUser</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@CouchDB</span>\Id</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">protected</span> $id;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@CouchDB</span>\ReferenceMany(targetDocument="AppBundle\CouchDocument\Group")</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">protected</span> $groups;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="启用分组控制器的路由"><a href="#启用分组控制器的路由" class="headerlink" title="启用分组控制器的路由"></a>启用分组控制器的路由</h4><p>你可以导入<code>group.xml</code>路由文件来使用内置的控制器来操作分组.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># app/config/routing.yml</span><br><span class="line">fos_user_group:</span><br><span class="line">    resource: &quot;@FOSUserBundle/Resources/config/routing/group.xml&quot;</span><br><span class="line">    prefix: /group</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;blockquote&gt;
&lt;p&gt;原文地址&lt;a href=&quot;http://symfony.com/doc/current/bundles/FOSUserBundle/groups.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://symfony.com/doc/current/bundles/FOSUserBundle/groups.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;FOSUserBundle允许你对用户进行分组. 分组是区分角色集合的一种方式. 一个组里面的用户会被授予这个组里面所有角色的权限.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Symfony支持角色继承, 所以从组中继承角色不是必须的. 如果在你的使用场景中继承了足够多的角色, 最好还是使用继承, 因为它更为高效.(分组功能需要数据库的驱动.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;你需要在配置文件中明确启用这个启用分组功能. 唯一强制性的就是要配置你实现了&lt;code&gt;FOS\UserBundle\Model\GroupInterface&lt;/code&gt;接口的&lt;code&gt;Group&lt;/code&gt;类的完全限定名(fully qualified class name).&lt;/p&gt;
    
    </summary>
    
      <category term="外文翻译" scheme="http://yoursite.com/categories/%E5%A4%96%E6%96%87%E7%BF%BB%E8%AF%91/"/>
    
    
      <category term="翻译" scheme="http://yoursite.com/tags/%E7%BF%BB%E8%AF%91/"/>
    
      <category term="PHP" scheme="http://yoursite.com/tags/PHP/"/>
    
      <category term="Symfony" scheme="http://yoursite.com/tags/Symfony/"/>
    
      <category term="FOSUserBundle" scheme="http://yoursite.com/tags/FOSUserBundle/"/>
    
  </entry>
  
  <entry>
    <title>FOSUserBundle的邮件服务</title>
    <link href="http://yoursite.com/2016/10/14/fosuserbundle-emails/"/>
    <id>http://yoursite.com/2016/10/14/fosuserbundle-emails/</id>
    <published>2016-10-14T12:52:19.000Z</published>
    <updated>2016-10-14T12:54:22.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>原文地址: <a href="http://symfony.com/doc/current/bundles/FOSUserBundle/emails.html" target="_blank" rel="noopener">http://symfony.com/doc/current/bundles/FOSUserBundle/emails.html</a></p></blockquote><p>FOSUserBundle内置了两种不同的发送邮件的实例.</p><h4 id="注册确认"><a href="#注册确认" class="headerlink" title="注册确认"></a>注册确认</h4><p>在一个新用户注册完成之前, 如果在FOSUserBundle中配置了必须通过邮件确认的步骤, 系统会发送一封带有链接的邮件到用户邮箱中. 用户访问链接之后会对用户账户进行验证并且激活.</p><p>通过邮件验证新用户注册默认是关闭的. 若要启用, 则需修改配置文件:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># app/config/config.yml</span><br><span class="line">fos_user:</span><br><span class="line">    # ...</span><br><span class="line">    registration:</span><br><span class="line">        confirmation:</span><br><span class="line">            enabled: true</span><br></pre></td></tr></table></figure><a id="more"></a><h4 id="重置密码"><a href="#重置密码" class="headerlink" title="重置密码"></a>重置密码</h4><p>当用户需要重置密码的时候, 通常也是通过发送邮件的方式进行的. FOSUserBundle提供了一个通过两个步骤重置密码的功能. 首先, 用户必须发送一个重置密码的请求. 在发送完请求之后, 会发送一封带有访问链接的邮件. 当访问链接时, 用户会通过被包含在url中的token识别出来. 当用户访问了链接并且token被验证之后, 一个要求输入新密码的表单将呈现在用户面前.</p><h4 id="默认的发送邮件实现"><a href="#默认的发送邮件实现" class="headerlink" title="默认的发送邮件实现"></a>默认的发送邮件实现</h4><p>FOSUserBundle带有三种邮件实现. 他们的服务id如下:</p><ul><li><code>fos_user.mailer.default</code>使用Swiftmailer来发送邮件的默认实现.</li><li><code>fos_user.mailer.twig_swift</code>使用Swiftmailer发送邮件并且用twig区块来渲染消息.</li><li><code>fos_user.mailer.noop</code>是一个不执行任何操作的邮件实现, 所以他不会发送邮件.</li></ul><blockquote><p><code>fos_user.mailer.noop</code>邮件服务是在你不需要发送邮件服务, 并且不在应用中安装SwiftmailerBundle的时候使用的. 如果你留下了默认的邮件配置, 并且没有注册SwiftmailerBundle, 你会收到一个依赖缺失的异常.</p></blockquote><h4 id="配置发送邮件的地址"><a href="#配置发送邮件的地址" class="headerlink" title="配置发送邮件的地址"></a>配置发送邮件的地址</h4><p>FOSUserBundle默认的邮件服务允许你设置发送邮件的邮件地址.  你可以配置全局的邮件地址, 也可以为每一封邮件配置地址.</p><p>若要为所有发送出去的邮件设置地址, 仅需像下面这样更新你的<code>fos_user</code>配置:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># app/config/config.yml</span><br><span class="line">fos_user:</span><br><span class="line">    #...</span><br><span class="line">    from_email:</span><br><span class="line">        address:        noreply@example.com</span><br><span class="line">        sender_name:    Demo App</span><br></pre></td></tr></table></figure><p>FOSUserBundle也提供了为每一封邮件设置邮件地址的灵活性.</p><p>若要为注册确认邮件设置地址, 仅需像下面这样更新你的<code>fos_user</code>配置:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"># app/config/config.yml</span><br><span class="line">fos_user:</span><br><span class="line">    #...</span><br><span class="line">    registration:</span><br><span class="line">        confirmation:</span><br><span class="line">            from_email:</span><br><span class="line">                address:        registration@example.com</span><br><span class="line">                sender_name:    Demo Registration</span><br></pre></td></tr></table></figure><p>你也可以通过配置<code>fos_user</code>来设置重置密码请求发送出去的邮件地址:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"># app/config/config.yml</span><br><span class="line">fos_user:</span><br><span class="line">    #...</span><br><span class="line">    resetting:</span><br><span class="line">        email:</span><br><span class="line">            from_email:</span><br><span class="line">                address:        resetting@example.com</span><br><span class="line">                sender_name:    Demo Resetting</span><br></pre></td></tr></table></figure><h4 id="发送HTML邮件"><a href="#发送HTML邮件" class="headerlink" title="发送HTML邮件"></a>发送HTML邮件</h4><p>默认的邮件服务只是单纯的发送文本信息. 如果你想发送复合信息, 最简单的解决方案就是使用TwigSwiftMailer实现. 他为你的twig模板定义了三个区块:</p><ul><li><code>subject</code> 包含了邮件的主题</li><li><code>body_text</code> 渲染纯文本版本的消息</li><li><code>body_html</code>渲染html邮件</li></ul><p>下面是如何使用的方法, 你可以参考下面两种引用邮件模板文件的方法.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"># app/config/config.yml</span><br><span class="line">fos_user:</span><br><span class="line">    # ...</span><br><span class="line">    service:</span><br><span class="line">        mailer: fos_user.mailer.twig_swift</span><br><span class="line">    resetting:</span><br><span class="line">        email:</span><br><span class="line">            template:   email/password_resetting.email.twig</span><br><span class="line">    registration:</span><br><span class="line">        confirmation:</span><br><span class="line">            template:   FOSUserBundle:Registration:email.txt.twig</span><br></pre></td></tr></table></figure><figure class="highlight twig"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&#123;# app/Resources/views/email/password_resetting.email.twig #&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="template-tag">&#123;% <span class="name"><span class="keyword">block</span></span> subject %&#125;</span>Resetting your password<span class="template-tag">&#123;% <span class="name"><span class="keyword">endblock</span></span> %&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="template-tag">&#123;% <span class="name"><span class="keyword">block</span></span> body_text %&#125;</span></span><br><span class="line"><span class="template-tag">&#123;% <span class="name"><span class="keyword">autoescape</span></span> false %&#125;</span></span><br><span class="line">Hello <span class="template-variable">&#123;&#123; user.username &#125;&#125;</span> !</span><br><span class="line"></span><br><span class="line">You can reset your password by accessing <span class="template-variable">&#123;&#123; confirmationUrl &#125;&#125;</span></span><br><span class="line"></span><br><span class="line">Greetings,</span><br><span class="line">the App team</span><br><span class="line"><span class="template-tag">&#123;% <span class="name"><span class="keyword">endautoescape</span></span> %&#125;</span></span><br><span class="line"><span class="template-tag">&#123;% <span class="name"><span class="keyword">endblock</span></span> %&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="template-tag">&#123;% <span class="name"><span class="keyword">block</span></span> body_html %&#125;</span></span><br><span class="line"><span class="comment">&#123;#</span></span><br><span class="line"><span class="comment">    You can of course render the html directly here.</span></span><br><span class="line"><span class="comment">    Including a template as done here allows keeping things DRY by using</span></span><br><span class="line"><span class="comment">    the template inheritance in it</span></span><br><span class="line"><span class="comment">#&#125;</span></span><br><span class="line"><span class="template-tag">&#123;% <span class="name"><span class="keyword">include</span></span> 'email/password_resetting.html.twig' %&#125;</span></span><br><span class="line"><span class="template-tag">&#123;% <span class="name"><span class="keyword">endblock</span></span> %&#125;</span></span><br></pre></td></tr></table></figure><blockquote><p>HTML部分仅在<code>body_html</code>区块不为空的情况下才会显示在信息中.</p></blockquote><p>你可以在FOSUserBundle:Registration:email.txt.twig和FOSUserBundle:Resetting:email.txt.twig中查看默认的邮件模板.</p><h4 id="使用自定义邮件服务"><a href="#使用自定义邮件服务" class="headerlink" title="使用自定义邮件服务"></a>使用自定义邮件服务</h4><p>FOSUserBundle使用的默认的邮件服务依赖于Swiftmailer类库. 如果你想使用其他的类库来发送邮件, 发送HTML邮件或者简单的修改邮件内容, 你可以向下面这样来定义你自己的邮件服务.</p><p>首先你得创建一个实现了<code>FOS\UserBundle\Mailer\MailerInterface</code>接口的类. 接口如下:</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">FOS</span>\<span class="title">UserBundle</span>\<span class="title">Mailer</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">FOS</span>\<span class="title">UserBundle</span>\<span class="title">Model</span>\<span class="title">UserInterface</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span> Thibault Duplessis &lt;thibault.duplessis<span class="doctag">@gmail</span>.com&gt;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">interface</span> <span class="title">MailerInterface</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Send an email to a user to confirm the account creation</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> UserInterface $user</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">sendConfirmationEmailMessage</span><span class="params">(UserInterface $user)</span></span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * Send an email to a user to confirm the password reset</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> UserInterface $user</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">sendResettingEmailMessage</span><span class="params">(UserInterface $user)</span></span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>在你实现了你的自定义邮件类并且将它定义成了服务之后, 你需要更新你的配置文件, 以便FOSUserBundle能够正确的使用. 只要设置在<code>service</code>部分的<code>mailer</code>参数即可. 就像下面这样:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># app/config/config.yml</span><br><span class="line">fos_user:</span><br><span class="line">    # ...</span><br><span class="line">    service:</span><br><span class="line">        mailer: app.custom_fos_user_mailer</span><br></pre></td></tr></table></figure><p>你可以查看<a href="https://github.com/simplethings/ZetaWebmailBundle" target="_blank" rel="noopener">ZetaWebmailBundle</a>中的<a href="https://github.com/simplethings/ZetaWebmailBundle/blob/master/UserBundle/ZetaMailer.php" target="_blank" rel="noopener">ZetaMailer</a>类是如何实现<code>MailerInterface</code>的. 这个实现使用了 Zeta Components Mail 来发送邮件, 而不是Swiftmailer.</p>]]></content>
    
    <summary type="html">
    
      &lt;blockquote&gt;
&lt;p&gt;原文地址: &lt;a href=&quot;http://symfony.com/doc/current/bundles/FOSUserBundle/emails.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://symfony.com/doc/current/bundles/FOSUserBundle/emails.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;FOSUserBundle内置了两种不同的发送邮件的实例.&lt;/p&gt;
&lt;h4 id=&quot;注册确认&quot;&gt;&lt;a href=&quot;#注册确认&quot; class=&quot;headerlink&quot; title=&quot;注册确认&quot;&gt;&lt;/a&gt;注册确认&lt;/h4&gt;&lt;p&gt;在一个新用户注册完成之前, 如果在FOSUserBundle中配置了必须通过邮件确认的步骤, 系统会发送一封带有链接的邮件到用户邮箱中. 用户访问链接之后会对用户账户进行验证并且激活.&lt;/p&gt;
&lt;p&gt;通过邮件验证新用户注册默认是关闭的. 若要启用, 则需修改配置文件:&lt;/p&gt;
&lt;figure class=&quot;highlight plain&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;# app/config/config.yml&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;fos_user:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    # ...&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    registration:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        confirmation:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            enabled: true&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
    
    </summary>
    
      <category term="外文翻译" scheme="http://yoursite.com/categories/%E5%A4%96%E6%96%87%E7%BF%BB%E8%AF%91/"/>
    
    
      <category term="翻译" scheme="http://yoursite.com/tags/%E7%BF%BB%E8%AF%91/"/>
    
      <category term="PHP" scheme="http://yoursite.com/tags/PHP/"/>
    
      <category term="Symfony" scheme="http://yoursite.com/tags/Symfony/"/>
    
      <category term="FOSUserBundle" scheme="http://yoursite.com/tags/FOSUserBundle/"/>
    
  </entry>
  
  <entry>
    <title>FOSUserBundle用户名表单字段</title>
    <link href="http://yoursite.com/2016/10/12/fosuserbundle-username-form-type/"/>
    <id>http://yoursite.com/2016/10/12/fosuserbundle-username-form-type/</id>
    <published>2016-10-12T06:00:46.000Z</published>
    <updated>2016-10-12T06:06:27.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>原文地址: <a href="http://symfony.com/doc/current/bundles/FOSUserBundle/form_type.html" target="_blank" rel="noopener">http://symfony.com/doc/current/bundles/FOSUserBundle/form_type.html</a></p></blockquote><p>FOSUserBundle提供了一个名为<code>fos_user_username</code>的用户名表单字段.  它是一个文本输入框, 接受用户名并且将其添加至用户实例中:</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MessageFormType</span> <span class="keyword">extends</span> <span class="title">AbstractType</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">buildForm</span><span class="params">(FormBuilderInterface $builder, array $options)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        $builder-&gt;add(<span class="string">'recipient'</span>, <span class="string">'FOS\UserBundle\Form\Type\UsernameFormType'</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// if you are using Symfony &lt; 2.8 you should use the old name instead</span></span><br><span class="line">        <span class="comment">// $builder-&gt;add('recipient', 'fos_user_username');</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><blockquote><p>假如你不想在应用中使用这种表单字段, 可以删除容器服务中的配置来禁用它:</p><pre><code># app/config/config.ymlfos_user:    use_username_form_type: false</code></pre></blockquote>]]></content>
    
    <summary type="html">
    
      
      
        &lt;blockquote&gt;
&lt;p&gt;原文地址: &lt;a href=&quot;http://symfony.com/doc/current/bundles/FOSUserBundle/form_type.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://sy
      
    
    </summary>
    
      <category term="外文翻译" scheme="http://yoursite.com/categories/%E5%A4%96%E6%96%87%E7%BF%BB%E8%AF%91/"/>
    
    
      <category term="翻译" scheme="http://yoursite.com/tags/%E7%BF%BB%E8%AF%91/"/>
    
      <category term="PHP" scheme="http://yoursite.com/tags/PHP/"/>
    
      <category term="Symfony" scheme="http://yoursite.com/tags/Symfony/"/>
    
      <category term="FOSUserBundle" scheme="http://yoursite.com/tags/FOSUserBundle/"/>
    
  </entry>
  
  <entry>
    <title>FOSUserBundle之使用用户名或密码登录</title>
    <link href="http://yoursite.com/2016/10/12/fosuserbundle-logging-by-username-or-email/"/>
    <id>http://yoursite.com/2016/10/12/fosuserbundle-logging-by-username-or-email/</id>
    <published>2016-10-12T05:39:21.000Z</published>
    <updated>2016-10-12T06:02:20.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>原文地址<a href="http://symfony.com/doc/current/bundles/FOSUserBundle/logging_by_username_or_email.html" target="_blank" rel="noopener">http://symfony.com/doc/current/bundles/FOSUserBundle/logging_by_username_or_email.html</a></p></blockquote><p>在FOSUserBundle的1.3.0版本中, 内建了通过用户名或者邮件字段登录功能的实现. 要启用这个功能只需修改配置中的用户服务提供器的id即可.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># app/config/security.yml</span><br><span class="line">security:</span><br><span class="line">    providers:</span><br><span class="line">        fos_userbundle:</span><br><span class="line">            id: fos_user.user_provider.username_email</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;blockquote&gt;
&lt;p&gt;原文地址&lt;a href=&quot;http://symfony.com/doc/current/bundles/FOSUserBundle/logging_by_username_or_email.html&quot; target=&quot;_blank&quot; rel=&quot;no
      
    
    </summary>
    
      <category term="外文翻译" scheme="http://yoursite.com/categories/%E5%A4%96%E6%96%87%E7%BF%BB%E8%AF%91/"/>
    
    
      <category term="翻译" scheme="http://yoursite.com/tags/%E7%BF%BB%E8%AF%91/"/>
    
      <category term="PHP" scheme="http://yoursite.com/tags/PHP/"/>
    
      <category term="Symfony" scheme="http://yoursite.com/tags/Symfony/"/>
    
      <category term="FOSUserBundle" scheme="http://yoursite.com/tags/FOSUserBundle/"/>
    
  </entry>
  
  <entry>
    <title>FOSUserBundle命令行管理工具</title>
    <link href="http://yoursite.com/2016/10/11/fosuserbundle-command-line-tools/"/>
    <id>http://yoursite.com/2016/10/11/fosuserbundle-command-line-tools/</id>
    <published>2016-10-11T06:52:05.000Z</published>
    <updated>2016-10-11T06:53:48.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>原文地址<a href="http://symfony.com/doc/current/bundles/FOSUserBundle/command_line_tools.html" target="_blank" rel="noopener">http://symfony.com/doc/current/bundles/FOSUserBundle/command_line_tools.html</a></p></blockquote><p>FOSUserBundle提供了大量的命令行工具来帮助你管理应用中的用户. 有这些命令任务可用:</p><ol><li>Create a User  <em>(创建用户)</em></li><li>Activate a User <em>(激活用户)</em></li><li>Deactivate a User <em>(停用用户)</em></li><li>Promote a User <em>(设置用户权限)</em></li><li>Demote a User <em>(清除用户权限)</em></li><li>Change a User’s Password <em>( 重置用户密码)</em></li></ol><blockquote><p>在使用这些命令行之前, 你需要正确的安装以及配置好FOSUserBundle</p></blockquote><blockquote><p>此文中引用的是Symfony3的控制<code>bin/console</code>. 如果你使用的Symfony2, 请调用<code>app/console</code>.</p></blockquote><a id="more"></a><h4 id="创建用户"><a href="#创建用户" class="headerlink" title="创建用户"></a>创建用户</h4><p>你可以在应用中使用<code>fos:user:create</code>命令来创建用户. 这个命令包含三个参数, <code>username</code>,  <code>email</code>, 和 <code>password</code>.<br>假如你需要创建一个用户名为<code>testuser</code>, 邮箱为<a href="mailto:`test@example.com" target="_blank" rel="noopener">`test@example.com</a><code>, 密码为</code>p@ssword`的用户, 则执行下面的命令</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">php bin/console fos:user:create testuser test@example.com p@ssword</span><br></pre></td></tr></table></figure><p>若没有传递任何参数到此命令中, 则程序会自动询问你相应的信息. 假设你运行了下面这条命令, 你则会被询问去输入用户的<code>email</code> 和 <code>password</code>.</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">php bin/console fos:user:create testuser</span><br></pre></td></tr></table></figure><p>你还可在命令中添加两个选项. <code>--super-admin</code>以及<code>--inactive</code>.<br>若输入了<code>--super-admin</code>选项, 则会将创建的用户标记为超级管理员. 超级管理员拥有应用中的所有权限. 下面是例子:</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">php bin/console fos:user:create adminuser --super-admin</span><br></pre></td></tr></table></figure><p>若输入了<code>--inactive</code>, 则创建的用户将无法登陆, 除非该用户被激活.</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">php bin/console fos:user:create testuser --inactive</span><br></pre></td></tr></table></figure><h4 id="激活用户"><a href="#激活用户" class="headerlink" title="激活用户"></a>激活用户</h4><p><code>fos:user:activate</code>命令将激活一个未激活用户. 此命令必须包含一个<code>username</code>的参数来指定激活哪一个用户. 若为输入<code>username</code> 则会提示你来输入用户名. 下面是例子:</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ php app/console fos:user:activate testuser</span><br><span class="line">$ <span class="comment"># OR if you are using Symfony &gt;= 2.8 with the new directory structure</span></span><br><span class="line">$ php bin/console fos:user:activate testuser</span><br></pre></td></tr></table></figure><h4 id="停用用户"><a href="#停用用户" class="headerlink" title="停用用户"></a>停用用户</h4><p><code>fos:user:deactivate</code>命令可以禁用用户. 和激活用户的命令一样, 此命令也必须包含一个<code>username</code>的参数来指定禁用哪一个用户. 若未提供用户名, 则会被提示输入<code>username</code>. 下面是例子</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ php app/console fos:user:deactivate testuser</span><br><span class="line">$ <span class="comment"># OR if you are using Symfony &gt;= 2.8 with the new directory structure</span></span><br><span class="line">$ php bin/console fos:user:deactivate testuser</span><br></pre></td></tr></table></figure><h4 id="设置用户权限"><a href="#设置用户权限" class="headerlink" title="设置用户权限"></a>设置用户权限</h4><p><code>fos:user:promote</code>命令能够让你为一个用户添加一个角色或者使用户成为一个超级管理员.<br>假如你要为一个用户添加一个<code>role</code> <em>(角色)</em>, 你只需要将第一个参数设定为要添加的用户名, 第二个参数作为角色名即可.</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">php bin/console fos:user:promote testuser ROLE_ADMIN</span><br></pre></td></tr></table></figure><p>你可以通过在用户名后面添加<code>--super</code>选项, 将一个用户设定为超级管理员.</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ php bin/console fos:user:promote testuser --super</span><br></pre></td></tr></table></figure><p>若你没有输入任何参数, 则你会被询问来输入这些参数.</p><blockquote><p>你可以不同时指定<code>role</code>参数和<code>--super</code>选项.</p></blockquote><h4 id="清除用户权限"><a href="#清除用户权限" class="headerlink" title="清除用户权限"></a>清除用户权限</h4><p><code>fos:user:demote</code>命令与为用户添加权限相似, 但功能相反.  你也可以使用这个命令来撤销一个超级管理员用户.<br>假如要移除一个用户的权限, 则需要将命令中的第一个参数设置为用户名, 第二个参数则为用户的角色.</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">php bin/console fos:user:demote testuser ROLE_ADMIN</span><br></pre></td></tr></table></figure><p>要撤销一个超级管理员用户, 仅需设置用户名参数, 然后再加上<code>--super</code>选项即可.</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">php bin/console fos:user:demote testuser --super</span><br></pre></td></tr></table></figure><blockquote><p>你可以不同时指定<code>role</code>参数和<code>--super</code>选项.</p></blockquote><h4 id="重置用户密码"><a href="#重置用户密码" class="headerlink" title="重置用户密码"></a>重置用户密码</h4><p><code>fos:user:change-password</code>命令提供一个简单的方式来修改用户密码. 这个命令有两个参数: 用户名<em>(username)</em>, 新密码<em>(password)</em>.</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">php bin/console fos:user:change-password testuser newp@ssword</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;blockquote&gt;
&lt;p&gt;原文地址&lt;a href=&quot;http://symfony.com/doc/current/bundles/FOSUserBundle/command_line_tools.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://symfony.com/doc/current/bundles/FOSUserBundle/command_line_tools.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;FOSUserBundle提供了大量的命令行工具来帮助你管理应用中的用户. 有这些命令任务可用:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a User  &lt;em&gt;(创建用户)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Activate a User &lt;em&gt;(激活用户)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Deactivate a User &lt;em&gt;(停用用户)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Promote a User &lt;em&gt;(设置用户权限)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Demote a User &lt;em&gt;(清除用户权限)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Change a User’s Password &lt;em&gt;( 重置用户密码)&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;在使用这些命令行之前, 你需要正确的安装以及配置好FOSUserBundle&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;此文中引用的是Symfony3的控制&lt;code&gt;bin/console&lt;/code&gt;. 如果你使用的Symfony2, 请调用&lt;code&gt;app/console&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
    
    </summary>
    
      <category term="外文翻译" scheme="http://yoursite.com/categories/%E5%A4%96%E6%96%87%E7%BF%BB%E8%AF%91/"/>
    
    
      <category term="翻译" scheme="http://yoursite.com/tags/%E7%BF%BB%E8%AF%91/"/>
    
      <category term="PHP" scheme="http://yoursite.com/tags/PHP/"/>
    
      <category term="Symfony" scheme="http://yoursite.com/tags/Symfony/"/>
    
      <category term="FOSUserBundle" scheme="http://yoursite.com/tags/FOSUserBundle/"/>
    
  </entry>
  
  <entry>
    <title>关于FOSUserBundle的用户管理服务</title>
    <link href="http://yoursite.com/2016/10/09/about-fosuserbundle-user-manager/"/>
    <id>http://yoursite.com/2016/10/09/about-fosuserbundle-user-manager/</id>
    <published>2016-10-09T13:06:14.000Z</published>
    <updated>2016-10-11T04:02:17.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>原文地址<a href="http://symfony.com/doc/current/bundles/FOSUserBundle/user_manager.html" target="_blank" rel="noopener">http://symfony.com/doc/current/bundles/FOSUserBundle/user_manager.html</a></p></blockquote><p>所有用户操作都实现了<code>FOS\UserBundle\Model\UserManagerInterface</code>接口, 从而实现了与存储方式的分离.  使用这个接口可以确保你能够随意的改变存储方式. FOSUserBundle提供的默认控制器使用的是配置中的用户管理, 而不是直接调用的数据存储层.</p><a id="more"></a><p>如果将<code>db_driver</code>配置为<code>orm</code>, 这个服务则为<code>FOS\UserBundle\Doctrine\UserManager</code>的实例.</p><p>如果将<code>db_driver</code>配置为<code>mongodb</code>, 这个服务则为<code>FOS\UserBundle\Doctrine\UserManager</code>的实例.</p><p>如果将<code>db_driver</code>配置为<code>couchdb</code>, 这个服务则为<code>FOS\UserBundle\Doctrine\UserManager</code>的实例.</p><p>如果将<code>db_driver</code>配置为<code>propel</code>, 这个服务则为<code>FOS\UserBundle\Propel\UserManager</code>的实例.</p><h4 id="调用用户管理服务"><a href="#调用用户管理服务" class="headerlink" title="调用用户管理服务"></a>调用用户管理服务</h4><p>用户管理是作为<code>fos_user.user_manager</code>服务在容器中使用的.</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$userManager = $container-&gt;get(<span class="string">'fos_user.user_manager'</span>);</span><br></pre></td></tr></table></figure><h4 id="创建一个新用户"><a href="#创建一个新用户" class="headerlink" title="创建一个新用户"></a>创建一个新用户</h4><p>可以使用用户管理来创建一个用户类的实例.</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$user = $userManager-&gt;createUser();</span><br></pre></td></tr></table></figure><p><code>$user</code>则为用户类的一个实例.</p><blockquote><p>如果你的构造函数中强制了一些参数, 这个方法会变得不可用.</p></blockquote><h4 id="检索用户"><a href="#检索用户" class="headerlink" title="检索用户"></a>检索用户</h4><p>用户管理服务有一些基于唯一字段(用户名, 电子邮件, 已验证的token)的查询方法和一个提取已有用户的方法.</p><ul><li><code>findUserByUsername($username)</code></li><li><code>findUserByEmail($email)</code></li><li><code>findUserByUsernameOrEmail($value)</code></li><li><code>findUserByConfirmationToken($token)</code></li><li><code>findUserBy(array(&#39;id&#39;=&gt;$id))</code></li><li><code>findUsers()</code></li></ul><p>你可以使用用户服务中的<code>updateUser</code>方法来保存用户对象. 这个方法会更新编码后的密码以及一些常用字段, 然后保存.</p><h4 id="更新用户对象"><a href="#更新用户对象" class="headerlink" title="更新用户对象"></a>更新用户对象</h4><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$user = $userManager-&gt;createUser();</span><br><span class="line">$user-&gt;setUsername(<span class="string">'John'</span>);</span><br><span class="line">$user-&gt;setEmail(<span class="string">'john.doe@example.com'</span>);</span><br><span class="line"></span><br><span class="line">$userManager-&gt;updateUser($user);</span><br></pre></td></tr></table></figure><blockquote><p>FOSUserBundle在程序中自带一个Doctrine监听器来处理密码以及常用字段的更新. 假如你始终使用用户管理服务来保存用户, 你也许会想禁用这个监听器来提高应用的性能.</p><pre><code># app/config/config.ymlfos_user:    # ...   use_listener: false</code></pre></blockquote><blockquote><p>Propel实现中没有添加此监听器, 所以你需要调用用户管理服务中的方法来保存用户信息.</p></blockquote><blockquote><p>对于Doctrine实现, 当在请求<code>updateUser</code>方法时, 默认的行为会去刷新工作单元. 你可以添加一个<code>false</code>参数来禁止刷新. 这相当于请求<code>updateCanonicalFields</code>和<code>updatePassword</code>方法.</p></blockquote><p>示例:</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MainController</span> <span class="keyword">extends</span> <span class="title">Controller</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">updateAction</span><span class="params">($id)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        $user = <span class="comment">// get a user from the datastore</span></span><br><span class="line"></span><br><span class="line">        $user-&gt;setEmail($newEmail);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">$this</span>-&gt;get(<span class="string">'fos_user.user_manager'</span>)-&gt;updateUser($user, <span class="keyword">false</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// make more modifications to the database</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">$this</span>-&gt;getDoctrine()-&gt;getManager()-&gt;flush();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="重写用户管理服务"><a href="#重写用户管理服务" class="headerlink" title="重写用户管理服务"></a>重写用户管理服务</h4><p>你可以配置一个实现了<code>FOS\UserBundle\Model\UserManagerInterface</code>接口的服务来替代默认的用户管理服务. 默认实现的id为<code>fos_user.user_manager.default</code>.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">fos_user:</span><br><span class="line">    # ...</span><br><span class="line">    service:</span><br><span class="line">        user_manager: custom_user_manager_id</span><br></pre></td></tr></table></figure><p>自定义的实现可以继承<code>FOS\UserBundle\Model\UserManager</code>从而复用现成逻辑.</p><h4 id="整合SecurityBundle"><a href="#整合SecurityBundle" class="headerlink" title="整合SecurityBundle"></a>整合SecurityBundle</h4><p>FOSUserBundle在<code>UserManagerInterface</code>顶部提供了一些<code>Symfony\Component\Security\Core\UserProviderInterface</code>的实现.</p><p>虽然框架內建的用户管理服务也实现了<code>Symfony\Component\Security\Core\User\UserProviderInterface</code>, 使用这个实现作为用户生成器已经过时了并且将在将来的版本中移除.<br> 请使用<code>FOS\UserBundle\Security\UserProvider</code>来替换它.</p>]]></content>
    
    <summary type="html">
    
      &lt;blockquote&gt;
&lt;p&gt;原文地址&lt;a href=&quot;http://symfony.com/doc/current/bundles/FOSUserBundle/user_manager.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://symfony.com/doc/current/bundles/FOSUserBundle/user_manager.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所有用户操作都实现了&lt;code&gt;FOS\UserBundle\Model\UserManagerInterface&lt;/code&gt;接口, 从而实现了与存储方式的分离.  使用这个接口可以确保你能够随意的改变存储方式. FOSUserBundle提供的默认控制器使用的是配置中的用户管理, 而不是直接调用的数据存储层.&lt;/p&gt;
    
    </summary>
    
      <category term="外文翻译" scheme="http://yoursite.com/categories/%E5%A4%96%E6%96%87%E7%BF%BB%E8%AF%91/"/>
    
    
      <category term="翻译" scheme="http://yoursite.com/tags/%E7%BF%BB%E8%AF%91/"/>
    
      <category term="PHP" scheme="http://yoursite.com/tags/PHP/"/>
    
      <category term="Symfony" scheme="http://yoursite.com/tags/Symfony/"/>
    
      <category term="FOSUserBundle" scheme="http://yoursite.com/tags/FOSUserBundle/"/>
    
  </entry>
  
  <entry>
    <title>重写FOSUserBundle的默认表单</title>
    <link href="http://yoursite.com/2016/10/07/fosuserbundle-overriding-default-forms/"/>
    <id>http://yoursite.com/2016/10/07/fosuserbundle-overriding-default-forms/</id>
    <published>2016-10-07T14:07:41.000Z</published>
    <updated>2016-10-11T04:02:46.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>原文地址<a href="http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_forms.html" target="_blank" rel="noopener">http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_forms.html</a></p></blockquote><h4 id="重写表单类型"><a href="#重写表单类型" class="headerlink" title="重写表单类型"></a>重写表单类型</h4><p>FOSUserBundle为新用户注册, 更新用户信息, 修改密码等功能封装了默认的表单. 这些表单能很好的作用在默认的类以及控制器上. 但假如你想在你的<code>User</code>类里面添加更多的属性, 或者想在注册表单里面添加一些选项时, 就得去修改默认的表单.</p><a id="more"></a><p>假设你创建了一个<code>AppBundle\Entity\User</code>的用户类. 在这个类里面, 你必须添加一个<code>name</code>属性跟用户名以及邮箱地址同时保存下来.此时, 当一个用户在你的网站注册时, 他必须填写他们的姓名以及用户名和邮箱, 密码. 下面的代码是添加了<code>$name</code>属性以及验证的例子.</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// src/AppBundle/Entity/User.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">FOS</span>\<span class="title">UserBundle</span>\<span class="title">Model</span>\<span class="title">User</span> <span class="title">as</span> <span class="title">BaseUser</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">Doctrine</span>\<span class="title">ORM</span>\<span class="title">Mapping</span> <span class="title">as</span> <span class="title">ORM</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">Symfony</span>\<span class="title">Component</span>\<span class="title">Validator</span>\<span class="title">Constraints</span> <span class="title">as</span> <span class="title">Assert</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">User</span> <span class="keyword">extends</span> <span class="title">BaseUser</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ORM</span>\Id</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ORM</span>\Column(type="integer")</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ORM</span>\GeneratedValue(strategy="AUTO")</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">protected</span> $id;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ORM</span>\Column(type="string", length=255)</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@Assert</span>\NotBlank(message="Please enter your name.", groups=&#123;"Registration", "Profile"&#125;)</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@Assert</span>\Length(</span></span><br><span class="line"><span class="comment">     *     min=3,</span></span><br><span class="line"><span class="comment">     *     max=255,</span></span><br><span class="line"><span class="comment">     *     minMessage="The name is too short.",</span></span><br><span class="line"><span class="comment">     *     maxMessage="The name is too long.",</span></span><br><span class="line"><span class="comment">     *     groups=&#123;"Registration", "Profile"&#125;</span></span><br><span class="line"><span class="comment">     * )</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">protected</span> $name;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><blockquote><p>默认情况下, Registration验证组是在一个新用户注册时被使用的.  请确保将你的name属性添加到了命名为Registration的验证组, 除非你在配置文件中修改了这个值.</p></blockquote><p>如果你尝试使用默认的表单进行注册, 你会发现新添加的<code>name</code>属性并不在表单中. 你需要通过创建一个自定义表单类型并且进行配置, 才能使表单正常运作.</p><p>第一步是在你的bundle中添加一个新的表单类型. 下面这个类继承自FOSUserBundle的<code>fos_user_registration</code>类型表单, 并且添加了自定义的<code>name</code>字段.</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// src/AppBundle/Form/RegistrationType.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">AppBundle</span>\<span class="title">Form</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">Symfony</span>\<span class="title">Component</span>\<span class="title">Form</span>\<span class="title">AbstractType</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">Symfony</span>\<span class="title">Component</span>\<span class="title">Form</span>\<span class="title">FormBuilderInterface</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">RegistrationType</span> <span class="keyword">extends</span> <span class="title">AbstractType</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">buildForm</span><span class="params">(FormBuilderInterface $builder, array $options)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        $builder-&gt;add(<span class="string">'name'</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">getParent</span><span class="params">()</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">'FOS\UserBundle\Form\Type\RegistrationFormType'</span>;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// Or for Symfony &lt; 2.8</span></span><br><span class="line">        <span class="comment">// return 'fos_user_registration';</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">getBlockPrefix</span><span class="params">()</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">'app_user_registration'</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// For Symfony 2.x</span></span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">getName</span><span class="params">()</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">$this</span>-&gt;getBlockPrefix();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><blockquote><p>如果你不想复用FOSUserBundle提供的默认字段, 则可以忽略<code>getParent</code>方法, 自己添加所有的字段.</p></blockquote><p>你已经创建好了自定义表单类型, 接着就是将它定义为一个服务并且添加相应的tag. tag的<code>name</code>值必须为<code>form.type</code>并且<code>alias</code>值必须与在添加的表单类型中的<code>getName</code>方法返回的字符串相同. <code>alias</code>是要告诉FOSUserBundle使用哪个自定义表单类型的名称.<br>下面是你的表单服务的配置示例:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># app/config/services.yml</span><br><span class="line">services:</span><br><span class="line">    app.form.registration:</span><br><span class="line">        class: AppBundle\Form\RegistrationType</span><br><span class="line">        tags:</span><br><span class="line">            - &#123; name: form.type, alias: app_user_registration &#125;</span><br></pre></td></tr></table></figure><p>最后你需要更新你的FOSUserBundle的配置信息, 以便让FOSUserBundle知道要使用哪个表单来替换默认的表单. 下面是替换注册表单的示例配置.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"># app/config/config.yml</span><br><span class="line">fos_user:</span><br><span class="line">    # ...</span><br><span class="line">    registration:</span><br><span class="line">        form:</span><br><span class="line">            type: AppBundle\Form\RegistrationType</span><br><span class="line">            # if you are using Symfony &lt; 2.8 you should use the type name instead</span><br><span class="line">            # type: app_user_registration</span><br></pre></td></tr></table></figure><p>注意在配置文件中是如何使用你的表单类型服务配置中tag的<code>alias</code>值来告诉FOSUserBundle使用你的自定义表单的.</p><blockquote><p>如果你需要在处理表单的时候添加一些逻辑, 你可以添加一个监听者<a href="/2016/10/01/fosuserbundle-hooking-into-the-controller">挂载到控制器</a></p></blockquote>]]></content>
    
    <summary type="html">
    
      &lt;blockquote&gt;
&lt;p&gt;原文地址&lt;a href=&quot;http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_forms.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_forms.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;重写表单类型&quot;&gt;&lt;a href=&quot;#重写表单类型&quot; class=&quot;headerlink&quot; title=&quot;重写表单类型&quot;&gt;&lt;/a&gt;重写表单类型&lt;/h4&gt;&lt;p&gt;FOSUserBundle为新用户注册, 更新用户信息, 修改密码等功能封装了默认的表单. 这些表单能很好的作用在默认的类以及控制器上. 但假如你想在你的&lt;code&gt;User&lt;/code&gt;类里面添加更多的属性, 或者想在注册表单里面添加一些选项时, 就得去修改默认的表单.&lt;/p&gt;
    
    </summary>
    
      <category term="外文翻译" scheme="http://yoursite.com/categories/%E5%A4%96%E6%96%87%E7%BF%BB%E8%AF%91/"/>
    
    
      <category term="翻译" scheme="http://yoursite.com/tags/%E7%BF%BB%E8%AF%91/"/>
    
      <category term="PHP" scheme="http://yoursite.com/tags/PHP/"/>
    
      <category term="Symfony" scheme="http://yoursite.com/tags/Symfony/"/>
    
      <category term="FOSUserBundle" scheme="http://yoursite.com/tags/FOSUserBundle/"/>
    
  </entry>
  
  <entry>
    <title>Symfony框架之重写FOSUserBundle的默认控制器</title>
    <link href="http://yoursite.com/2016/10/04/fosuserbundle-overriding-default-controllers/"/>
    <id>http://yoursite.com/2016/10/04/fosuserbundle-overriding-default-controllers/</id>
    <published>2016-10-04T13:49:41.000Z</published>
    <updated>2016-10-04T13:54:43.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>原文地址<a href="http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_controllers.html" target="_blank" rel="noopener">http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_controllers.html</a></p></blockquote><p>FOSUserBundle中默认的控制器提供了大量的功能来满足日常使用. 但在你的应用中, 通常需要继承这些功能, 并且在里面添加你自己的业务逻辑.<br><a id="more"></a></p><blockquote><p>重写控制器需要复制所有的action逻辑. 大多数情况下使用事件来实现功能会更简单一些. 只有在没有其他办法的情况下才会考虑重写控制器.</p></blockquote><p>重写控制器的第一步是创建一个继承FOSUserBundle的子bundle. 下面的代码片段定义了一个名为<code>AcmeUserBundle</code>的继承自FOSUserBundle的子bundle.</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// src/Acme/UserBundle/AcmeUserBundle.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">Acme</span>\<span class="title">UserBundle</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">Symfony</span>\<span class="title">Component</span>\<span class="title">HttpKernel</span>\<span class="title">Bundle</span>\<span class="title">Bundle</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">AcmeUserBundle</span> <span class="keyword">extends</span> <span class="title">Bundle</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">getParent</span><span class="params">()</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">'FOSUserBundle'</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><blockquote><p>Symfony框架只中每个bundle只能有一个子bundle. 这意味着你不能再创建另外一个继承自FOSUserBundle的子bundle.</p></blockquote><p>现在你已经创建了一个新的子bundle, 你可以创建一个与你想重写的控制器路径以及名称相同的控制器类. 在这个例子中,通过扩展FOSUserBundle中的<code>RegistrationController</code>类来实现对<code>RegistrationController</code>的方法中额外的功能的重写.<br>下面的例子中重写了<code>registerAction</code>方法. 它使用了base 控制器的代码并且添加了新用户登录的逻辑.</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// src/Acme/UserBundle/Controller/RegistrationController.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">Acme</span>\<span class="title">UserBundle</span>\<span class="title">Controller</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">Symfony</span>\<span class="title">Component</span>\<span class="title">HttpFoundation</span>\<span class="title">RedirectResponse</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">FOS</span>\<span class="title">UserBundle</span>\<span class="title">Controller</span>\<span class="title">RegistrationController</span> <span class="title">as</span> <span class="title">BaseController</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">Symfony</span>\<span class="title">Component</span>\<span class="title">HttpFoundation</span>\<span class="title">Request</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">RegistrationController</span> <span class="keyword">extends</span> <span class="title">BaseController</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">registerAction</span><span class="params">(Request $request)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        $form = <span class="keyword">$this</span>-&gt;container-&gt;get(<span class="string">'fos_user.registration.form'</span>);</span><br><span class="line">        $formHandler = <span class="keyword">$this</span>-&gt;container-&gt;get(<span class="string">'fos_user.registration.form.handler'</span>);</span><br><span class="line">        $confirmationEnabled = <span class="keyword">$this</span>-&gt;container-&gt;getParameter(<span class="string">'fos_user.registration.confirmation.enabled'</span>);</span><br><span class="line"></span><br><span class="line">        $process = $formHandler-&gt;process($confirmationEnabled);</span><br><span class="line">        <span class="keyword">if</span> ($process) &#123;</span><br><span class="line">            $user = $form-&gt;getData();</span><br><span class="line"></span><br><span class="line">            <span class="comment">/*****************************************************</span></span><br><span class="line"><span class="comment">             * Add new functionality (e.g. log the registration) *</span></span><br><span class="line"><span class="comment">             *****************************************************/</span></span><br><span class="line">            <span class="keyword">$this</span>-&gt;container-&gt;get(<span class="string">'logger'</span>)-&gt;info(</span><br><span class="line">                sprintf(<span class="string">'New user registration: %s'</span>, $user)</span><br><span class="line">            );</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> ($confirmationEnabled) &#123;</span><br><span class="line">                <span class="keyword">$this</span>-&gt;container-&gt;get(<span class="string">'session'</span>)-&gt;set(<span class="string">'fos_user_send_confirmation_email/email'</span>, $user-&gt;getEmail());</span><br><span class="line">                $route = <span class="string">'fos_user_registration_check_email'</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="keyword">$this</span>-&gt;authenticateUser($user);</span><br><span class="line">                $route = <span class="string">'fos_user_registration_confirmed'</span>;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">$this</span>-&gt;setFlash(<span class="string">'fos_user_success'</span>, <span class="string">'registration.flash.user_created'</span>);</span><br><span class="line">            $url = <span class="keyword">$this</span>-&gt;container-&gt;get(<span class="string">'router'</span>)-&gt;generate($route);</span><br><span class="line"></span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> RedirectResponse($url);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">$this</span>-&gt;container-&gt;get(<span class="string">'templating'</span>)-&gt;renderResponse(<span class="string">'FOSUserBundle:Registration:register.html.twig'</span>, <span class="keyword">array</span>(</span><br><span class="line">            <span class="string">'form'</span> =&gt; $form-&gt;createView(),</span><br><span class="line">        ));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><blockquote><p>如果在你想重写时不继承FOSUserBundle控制器类而是继承自FrameworkBundle提供的容器或者控制器, 那你就必须实现FOSUserBundle 的控制器所有的方法.</p></blockquote>]]></content>
    
    <summary type="html">
    
      &lt;blockquote&gt;
&lt;p&gt;原文地址&lt;a href=&quot;http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_controllers.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_controllers.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;FOSUserBundle中默认的控制器提供了大量的功能来满足日常使用. 但在你的应用中, 通常需要继承这些功能, 并且在里面添加你自己的业务逻辑.&lt;br&gt;
    
    </summary>
    
      <category term="外文翻译" scheme="http://yoursite.com/categories/%E5%A4%96%E6%96%87%E7%BF%BB%E8%AF%91/"/>
    
    
      <category term="翻译" scheme="http://yoursite.com/tags/%E7%BF%BB%E8%AF%91/"/>
    
      <category term="PHP" scheme="http://yoursite.com/tags/PHP/"/>
    
      <category term="Symfony" scheme="http://yoursite.com/tags/Symfony/"/>
    
      <category term="FOSUserBundle" scheme="http://yoursite.com/tags/FOSUserBundle/"/>
    
  </entry>
  
  <entry>
    <title>Symfony框架之FOSUserBundle挂载到控制器</title>
    <link href="http://yoursite.com/2016/10/01/fosuserbundle-hooking-into-the-controller/"/>
    <id>http://yoursite.com/2016/10/01/fosuserbundle-hooking-into-the-controller/</id>
    <published>2016-10-01T15:05:11.000Z</published>
    <updated>2016-10-01T15:07:17.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>原文地址<a href="http://symfony.com/doc/current/bundles/FOSUserBundle/controller_events.html" target="_blank" rel="noopener">http://symfony.com/doc/current/bundles/FOSUserBundle/controller_events.html</a></p></blockquote><p>通过FOSUserBundle包装过的控制器提供了一些能够满足一般需要的功能. 不过你可能需要在你的应用中扩展这些功能, 并且加入你自己的业务逻辑.</p><a id="more"></a><p>出于此目的, 控制器在他们的逻辑中的多个地方触发了一些事件. 所有的事件都能在<code>FOS\UserBundle\FOSUserEvents</code>类中的常量找到.</p><p>所有的控制器都遵循一个约定: 他们会在表单验证之后保存用户数据之前触发一个<code>SUCCESS</code>事件, 并且在保存用户数据之后触发一个<code>COMPLETED</code>事件.因此你不想使用默认的重定向, 你可以在所有的<code>SUCCESS</code>事件之后你可以设置一个响应. 所有的<code>COMPLETED</code>事件允许你在控制器返回之前设置一个响应.</p><p>带表单的控制器在实体加载完毕之后通常会触发一个<code>INITIALIZE</code>事件, 而不是在表单创建之后.</p><p>例如,下面这个监听器会在重置密码之后跳转到homepage, 而不是profile页面:</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// src/Acme/UserBundle/EventListener/PasswordResettingListener.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">Acme</span>\<span class="title">UserBundle</span>\<span class="title">EventListener</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">FOS</span>\<span class="title">UserBundle</span>\<span class="title">FOSUserEvents</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">FOS</span>\<span class="title">UserBundle</span>\<span class="title">Event</span>\<span class="title">FormEvent</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">Symfony</span>\<span class="title">Component</span>\<span class="title">EventDispatcher</span>\<span class="title">EventSubscriberInterface</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">Symfony</span>\<span class="title">Component</span>\<span class="title">HttpFoundation</span>\<span class="title">RedirectResponse</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">Symfony</span>\<span class="title">Component</span>\<span class="title">Routing</span>\<span class="title">Generator</span>\<span class="title">UrlGeneratorInterface</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Listener responsible to change the redirection at the end of the password resetting</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">PasswordResettingListener</span> <span class="keyword">implements</span> <span class="title">EventSubscriberInterface</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="keyword">private</span> $router;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">__construct</span><span class="params">(UrlGeneratorInterface $router)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">$this</span>-&gt;router = $router;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * &#123;<span class="doctag">@inheritdoc</span>&#125;</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="function"><span class="keyword">function</span> <span class="title">getSubscribedEvents</span><span class="params">()</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">array</span>(</span><br><span class="line">            FOSUserEvents::RESETTING_RESET_SUCCESS =&gt; <span class="string">'onPasswordResettingSuccess'</span>,</span><br><span class="line">        );</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">onPasswordResettingSuccess</span><span class="params">(FormEvent $event)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        $url = <span class="keyword">$this</span>-&gt;router-&gt;generate(<span class="string">'homepage'</span>);</span><br><span class="line"></span><br><span class="line">        $event-&gt;setResponse(<span class="keyword">new</span> RedirectResponse($url));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>然后你可以在配置中注册这个监听器:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"># src/Acme/UserBundle/Resources/config/services.yml</span><br><span class="line">services:</span><br><span class="line">    acme_user.password_resetting:</span><br><span class="line">        class: Acme\UserBundle\EventListener\PasswordResettingListener</span><br><span class="line">        arguments: [&apos;@router&apos;]</span><br><span class="line">        tags:</span><br><span class="line">            - &#123; name: kernel.event_subscriber &#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;blockquote&gt;
&lt;p&gt;原文地址&lt;a href=&quot;http://symfony.com/doc/current/bundles/FOSUserBundle/controller_events.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://symfony.com/doc/current/bundles/FOSUserBundle/controller_events.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;通过FOSUserBundle包装过的控制器提供了一些能够满足一般需要的功能. 不过你可能需要在你的应用中扩展这些功能, 并且加入你自己的业务逻辑.&lt;/p&gt;
    
    </summary>
    
      <category term="外文翻译" scheme="http://yoursite.com/categories/%E5%A4%96%E6%96%87%E7%BF%BB%E8%AF%91/"/>
    
    
      <category term="翻译" scheme="http://yoursite.com/tags/%E7%BF%BB%E8%AF%91/"/>
    
      <category term="PHP" scheme="http://yoursite.com/tags/PHP/"/>
    
      <category term="Symfony" scheme="http://yoursite.com/tags/Symfony/"/>
    
      <category term="FOSUserBundle" scheme="http://yoursite.com/tags/FOSUserBundle/"/>
    
  </entry>
  
  <entry>
    <title>Symfony框架之重写FOSUserBundle的默认模板</title>
    <link href="http://yoursite.com/2016/09/28/overriding-default-fosuserbundle-templates/"/>
    <id>http://yoursite.com/2016/09/28/overriding-default-fosuserbundle-templates/</id>
    <published>2016-09-28T14:41:21.000Z</published>
    <updated>2016-09-28T14:55:54.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>原文地址: <a href="http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_templates.html" target="_blank" rel="noopener">http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_templates.html</a></p></blockquote><blockquote><p>如果你在应用中使用了FOSUserBundle, 你势必会想办法去重写这个bundle提供的默认模板.<br>虽然模板的名称是不可配置的, 但是Symfony框架也为我们提供了两种重写模板的方式.</p><ol><li>在<code>app/Resources</code>文件夹中定义一个同名模板文件.</li><li>创建一个继承了<code>FOSUserBundle</code>的bundle.</li></ol></blockquote><a id="more"></a><h3 id="举例-重写默认的-layout-html-twig"><a href="#举例-重写默认的-layout-html-twig" class="headerlink" title="举例:重写默认的 layout.html.twig"></a>举例:重写默认的 layout.html.twig</h3><p>推荐的做法是重写<code>Resources/views/layout.html.twig</code>模板, 这样能保证FOSUserBundle提供的页面能与你应用的页面风格保持一致. 下面是一个重写<code>layout.html.twig</code>的例子, 它包含了所有的重写选项.</p><p>FOSUserBundle提供的默认的<code>layout.html.twig</code>:</p><figure class="highlight twig"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">&lt;!DOCTYPE html&gt;</span><br><span class="line">&lt;html&gt;</span><br><span class="line">    &lt;head&gt;</span><br><span class="line">        &lt;meta charset="UTF-8" /&gt;</span><br><span class="line">    &lt;/head&gt;</span><br><span class="line">    &lt;body&gt;</span><br><span class="line">        &lt;div&gt;</span><br><span class="line">            <span class="template-tag">&#123;% <span class="name"><span class="keyword">if</span></span> is_granted("IS_AUTHENTICATED_REMEMBERED") %&#125;</span></span><br><span class="line">                <span class="template-variable">&#123;&#123; 'layout.logged_in_as'|trans(&#123;'%username%': app.user.username&#125;, 'FOSUserBundle') &#125;&#125;</span> |</span><br><span class="line">                &lt;a href="<span class="template-variable">&#123;&#123; path('fos_user_security_logout') &#125;&#125;</span>"&gt;</span><br><span class="line">                    <span class="template-variable">&#123;&#123; 'layout.logout'|trans(&#123;&#125;, 'FOSUserBundle') &#125;&#125;</span></span><br><span class="line">                &lt;/a&gt;</span><br><span class="line">            <span class="template-tag">&#123;% <span class="name">else</span> %&#125;</span></span><br><span class="line">                &lt;a href="<span class="template-variable">&#123;&#123; path('fos_user_security_login') &#125;&#125;</span>"&gt;<span class="template-variable">&#123;&#123; 'layout.login'|trans(&#123;&#125;, 'FOSUserBundle') &#125;&#125;</span>&lt;/a&gt;</span><br><span class="line">            <span class="template-tag">&#123;% <span class="name"><span class="keyword">endif</span></span> %&#125;</span></span><br><span class="line">        &lt;/div&gt;</span><br><span class="line"></span><br><span class="line">        <span class="template-tag">&#123;% <span class="name"><span class="keyword">for</span></span> type, messages in app.session.flashBag.all %&#125;</span></span><br><span class="line">            <span class="template-tag">&#123;% <span class="name"><span class="keyword">for</span></span> message in messages %&#125;</span></span><br><span class="line">                &lt;div class="<span class="template-variable">&#123;&#123; type &#125;&#125;</span>"&gt;</span><br><span class="line">                    <span class="template-variable">&#123;&#123; message|trans(&#123;&#125;, 'FOSUserBundle') &#125;&#125;</span></span><br><span class="line">                &lt;/div&gt;</span><br><span class="line">            <span class="template-tag">&#123;% <span class="name"><span class="keyword">endfor</span></span> %&#125;</span></span><br><span class="line">        <span class="template-tag">&#123;% <span class="name"><span class="keyword">endfor</span></span> %&#125;</span></span><br><span class="line"></span><br><span class="line">        &lt;div&gt;</span><br><span class="line">            <span class="template-tag">&#123;% <span class="name"><span class="keyword">block</span></span> fos_user_content %&#125;</span></span><br><span class="line">            <span class="template-tag">&#123;% <span class="name"><span class="keyword">endblock</span></span> fos_user_content %&#125;</span></span><br><span class="line">        &lt;/div&gt;</span><br><span class="line">    &lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure><p>如你所见, 它非常的简洁, 没有太多的结构, 所以你肯定会想用你应用中的布局文件来替换他. 在这个模板文件中主要要注意的地方就是名为<code>fos_user_content</code>的区块. 这是FOSUserBundle要在不同bundle的action中显示的内容, 所以你必须在你要重写的布局文件中包含这个区块.</p><p>下面的Twig模板是复写布局文件的例子.</p><figure class="highlight twig"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="template-tag">&#123;% <span class="name"><span class="keyword">block</span></span> title %&#125;</span>Demo Application<span class="template-tag">&#123;% <span class="name"><span class="keyword">endblock</span></span> %&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="template-tag">&#123;% <span class="name"><span class="keyword">block</span></span> content %&#125;</span></span><br><span class="line">    <span class="template-tag">&#123;% <span class="name"><span class="keyword">block</span></span> fos_user_content %&#125;</span><span class="template-tag">&#123;% <span class="name"><span class="keyword">endblock</span></span> %&#125;</span></span><br><span class="line"><span class="template-tag">&#123;% <span class="name"><span class="keyword">endblock</span></span> %&#125;</span></span><br></pre></td></tr></table></figure><p>上面的例子继承了你的应用中的布局. <code>content</code> 区块是每个页面中显示内容的主要区域. 这就是为何<code>fos_user_content</code> 区块要包含在它里面的原因. 这将使FOSUserBundle的输出能够像预期的一样集成到应用的布局中去, 看上去像一个整体.</p><h4 id="a-在app-Resources中创建一个新的模板文件"><a href="#a-在app-Resources中创建一个新的模板文件" class="headerlink" title="a)在app/Resources中创建一个新的模板文件"></a>a)在app/Resources中创建一个新的模板文件</h4><p>重写模板的最简单的方式是在你的<code>app/Resources</code>文件夹中创建一个新的模板. 为了重写<code>FOSUserBundle</code>文件夹中的<code>Resources/views/layout.html.twig</code>文件, 你应该将新的模板文件保存在<code>app/Resources/FOSUserBundle/views/layout.html.twig</code></p><p>正如你看到的, 这种方式是在你的<code>app/Resources</code>目录中直接创建一个同名bundle的文件夹. 然后将你要重写的模板按照原来的目录结构保存在里面.</p><h4 id="b-创建一个继承FOSUserBundle的bundle并且重写模板"><a href="#b-创建一个继承FOSUserBundle的bundle并且重写模板" class="headerlink" title="b)创建一个继承FOSUserBundle的bundle并且重写模板"></a>b)创建一个继承FOSUserBundle的bundle并且重写模板</h4><blockquote><p>这种方式相对上面的方式来说会复杂一些.除非你计划重写控制器以及模板, 不然还是使用另外一个方法比较好.</p></blockquote><p>如上所述, 你可以创建一个FOSUserBundle的子bundle, 并且将要重写的模板保存在与FOSUserBundle相同的位置.首先要做的是在你的bundle类中重写<code>getParent</code>方法.</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// src/Acme/UserBundle/AcmeUserBundle.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">Acme</span>\<span class="title">UserBundle</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">Symfony</span>\<span class="title">Component</span>\<span class="title">HttpKernel</span>\<span class="title">Bundle</span>\<span class="title">Bundle</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">AcmeUserBundle</span> <span class="keyword">extends</span> <span class="title">Bundle</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">getParent</span><span class="params">()</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">'FOSUserBundle'</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>通过你的bundle类中<code>getParent</code>方法返回的bundle的名称, 你可以告诉Symfony框架你的bundle是继承自FOSUserBundle的.</p><p>一旦你将你的bundle定义成了FOSUserBundle的子bundle, 你就可以重写父级bundle中的模板文件了. 若要重写布局文件, 只需要在<code>src/Acme/UserBundle/Resources/views</code>文件夹中创建一个名为<code>layout.html.twig</code>的文件. 注意此文件在bundle中的路径应该与在<code>FOSUserBundle</code>中的路径一样.</p><p>一旦在你的子bundle中重写了模板, 你就需要清理缓存, 即使是在开发环境中也要清理.</p><p><em>重写FOSUserBundle中其他的模板文件的方式跟此文中介绍的方式相同. </em></p>]]></content>
    
    <summary type="html">
    
      &lt;blockquote&gt;
&lt;p&gt;原文地址: &lt;a href=&quot;http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_templates.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://symfony.com/doc/current/bundles/FOSUserBundle/overriding_templates.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;如果你在应用中使用了FOSUserBundle, 你势必会想办法去重写这个bundle提供的默认模板.&lt;br&gt;虽然模板的名称是不可配置的, 但是Symfony框架也为我们提供了两种重写模板的方式.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在&lt;code&gt;app/Resources&lt;/code&gt;文件夹中定义一个同名模板文件.&lt;/li&gt;
&lt;li&gt;创建一个继承了&lt;code&gt;FOSUserBundle&lt;/code&gt;的bundle.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
    
    </summary>
    
      <category term="外文翻译" scheme="http://yoursite.com/categories/%E5%A4%96%E6%96%87%E7%BF%BB%E8%AF%91/"/>
    
    
      <category term="翻译" scheme="http://yoursite.com/tags/%E7%BF%BB%E8%AF%91/"/>
    
      <category term="PHP" scheme="http://yoursite.com/tags/PHP/"/>
    
      <category term="Symfony" scheme="http://yoursite.com/tags/Symfony/"/>
    
      <category term="FOSUserBundle" scheme="http://yoursite.com/tags/FOSUserBundle/"/>
    
  </entry>
  
  <entry>
    <title>Symfony框架之FOSUserBundle入门教程</title>
    <link href="http://yoursite.com/2016/09/15/getting-started-with-FOSUserBundle/"/>
    <id>http://yoursite.com/2016/09/15/getting-started-with-FOSUserBundle/</id>
    <published>2016-09-15T12:33:03.000Z</published>
    <updated>2016-10-14T12:56:22.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>原文地址: <a href="http://symfony.com/doc/current/bundles/FOSUserBundle/index.html" target="_blank" rel="noopener">http://symfony.com/doc/current/bundles/FOSUserBundle/index.html</a></p></blockquote><blockquote><p>Symfony的安全组件为你提供了一个灵活的框架, 它允许你从配置文件, 数据库, 或者其他任何你想象的到的地方来加载用户. FOSUserBundle则建立在此基础上, 更方便快速的将用户信息存储到数据库之中.</p></blockquote><p><strong>准备工作</strong><br>1.3.x版本的FOSUserBundle依赖于Symfony2.1+. 如果你使用的是Symfony2.0.x, 请使用1.2.x系列的版本.</p><a id="more"></a><p><strong>翻译</strong><br>如果你要使用此bundle提供的默认文本, 你必须保证你的配置文件中已经开启了翻译功能.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># app/config/config.yml</span><br><span class="line"></span><br><span class="line">framework:</span><br><span class="line">    translator: ~</span><br></pre></td></tr></table></figure><p>更多关于翻译的信息, 请点击<a href="https://symfony.com/doc/current/book/translation.html" target="_blank" rel="noopener">Symfonydocumentation</a></p><p><strong>安装</strong><br>整个安装过程有7个步骤:</p><ol><li>使用composer下载FOSUserBundle</li><li>启用Bundle</li><li>创建你的User类</li><li>配置应用中的security.yml文件</li><li>配置FOSUserBundle</li><li>导入FOSUserBundle的路由文件</li><li>更新数据库的Schema</li></ol><h3 id="步骤1-使用Composer下载FOSUserBundle"><a href="#步骤1-使用Composer下载FOSUserBundle" class="headerlink" title="步骤1:使用Composer下载FOSUserBundle"></a>步骤1:使用Composer下载FOSUserBundle</h3><p>使用composer安装bundle:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ composer require friendsofsymfony/user-bundle &quot;~2.0@dev&quot;</span><br></pre></td></tr></table></figure><p>Composer会将bundle安装到你项目中的<code>vendor/friendsofsymfony/user-bundle</code>文件夹内.<br>如果你遇到了缺少配置参数的错误, 例如 <code>The child node &quot;db_driver&quot; at path &quot;fos_user&quot; must be configured</code>, 你应该先完成<a href="#步骤5-配置FOSUserBundle">步骤5</a>, 然后再重新执行这一步.</p><h3 id="步骤2-启用Bundle"><a href="#步骤2-启用Bundle" class="headerlink" title="步骤2: 启用Bundle"></a>步骤2: 启用Bundle</h3><p>在kernel中启用此bundle:</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// app/AppKernel.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">registerBundles</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    $bundles = <span class="keyword">array</span>(</span><br><span class="line">        <span class="comment">// ...</span></span><br><span class="line">        <span class="keyword">new</span> FOS\UserBundle\FOSUserBundle(),</span><br><span class="line">        <span class="comment">// ...</span></span><br><span class="line">    );</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="步骤3-创建你的用户类"><a href="#步骤3-创建你的用户类" class="headerlink" title="步骤3:创建你的用户类"></a>步骤3:创建你的用户类</h3><p>FOSUserBundle自始至终是使用一些<code>User</code>类来操作数据库的 (MySql, MongoDB, CouchDB, 等等). 你首先应该为你的应用创建一个<code>User</code>类.这个类可以包含任何你觉得有用的方法和属性. 因为这是你的<code>User</code>类.<br>FOSUserBundle提供了一些已经映射了大多数字段的基类, 这个类能让你更简单的创建entity. 你可以这么使用:</p><ol><li>继承<code>User</code>的基类.</li><li>映射<code>id</code>字段.  它必须被设为protected, 因为在父类中他已经被定义过了.</li></ol><blockquote><p>当你继承了FOSUserBundle提供的已经做过映射的超类时, 不要定义其他已经定义好的映射.</p></blockquote><p>接下来你将看到根据你存储方式的不同如何来定义你的<code>User</code>类(Doctrine ORM, MongoDB ODM, 或 CouchDB ODM).</p><blockquote><p>如果在你的 <code>User</code> 类中重写了<code>__construct()</code>方法, 请务必执行 <code>parent::__construct()</code>, 因为<code>User</code>基类通过这个方法初始化了一些字段.</p></blockquote><p><strong>a)Doctrine ORM User class</strong></p><p>如果你通过Doctrine ORM来管理用户, 你的<code>User</code>类应该存在<code>Entity</code>命名空间之内, 就像这样.</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// src/AppBundle/Entity/User.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">AppBundle</span>\<span class="title">Entity</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">FOS</span>\<span class="title">UserBundle</span>\<span class="title">Model</span>\<span class="title">User</span> <span class="title">as</span> <span class="title">BaseUser</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">Doctrine</span>\<span class="title">ORM</span>\<span class="title">Mapping</span> <span class="title">as</span> <span class="title">ORM</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ORM</span>\Entity</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@ORM</span>\Table(name="fos_user")</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">User</span> <span class="keyword">extends</span> <span class="title">BaseUser</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ORM</span>\Id</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ORM</span>\Column(type="integer")</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@ORM</span>\GeneratedValue(strategy="AUTO")</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">protected</span> $id;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">__construct</span><span class="params">()</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">parent</span>::__construct();</span><br><span class="line">        <span class="comment">// your own logic</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><blockquote><p><code>user</code>在标准SQL中是一个保留字, 如果你需要使用这个保留字, 那就要用反引号把它包围起来.就像这样  @ORM\Table(name=”`user`“)</p></blockquote><p><strong>b)MongoDB User class</strong></p><p>假如你使用 Doctrine MongoDB ODM来操作你的用户, 那你的<code>User</code>类应该在你的bundle中的<code>Document</code>命名空间之内, 就像下面这样:</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// src/AppBundle/Document/User.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">AppBundle</span>\<span class="title">Document</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">FOS</span>\<span class="title">UserBundle</span>\<span class="title">Model</span>\<span class="title">User</span> <span class="title">as</span> <span class="title">BaseUser</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">Doctrine</span>\<span class="title">ODM</span>\<span class="title">MongoDB</span>\<span class="title">Mapping</span>\<span class="title">Annotations</span> <span class="title">as</span> <span class="title">MongoDB</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@MongoDB</span>\Document</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">User</span> <span class="keyword">extends</span> <span class="title">BaseUser</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@MongoDB</span>\Id(strategy="auto")</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">protected</span> $id;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">__construct</span><span class="params">()</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">parent</span>::__construct();</span><br><span class="line">        <span class="comment">// your own logic</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>c) CouchDB User class</strong><br>如果你通过Doctrine CouchDB ODM来错做用户, 你的<code>User</code>类应该在<code>CouchDocument</code>命名空间中, 就像这样:</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// src/AppBundle/CouchDocument/User.php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title">AppBundle</span>\<span class="title">CouchDocument</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">FOS</span>\<span class="title">UserBundle</span>\<span class="title">Model</span>\<span class="title">User</span> <span class="title">as</span> <span class="title">BaseUser</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">Doctrine</span>\<span class="title">ODM</span>\<span class="title">CouchDB</span>\<span class="title">Mapping</span>\<span class="title">Annotations</span> <span class="title">as</span> <span class="title">CouchDB</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@CouchDB</span>\Document</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">User</span> <span class="keyword">extends</span> <span class="title">BaseUser</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@CouchDB</span>\Id</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">protected</span> $id;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">__construct</span><span class="params">()</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="keyword">parent</span>::__construct();</span><br><span class="line">        <span class="comment">// your own logic</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="步骤4-配置应用中的security-yml文件"><a href="#步骤4-配置应用中的security-yml文件" class="headerlink" title="步骤4:配置应用中的security.yml文件"></a>步骤4:配置应用中的security.yml文件</h3><p>为了让Symfony的安全组件能够使用FOSUserBundle, 你需要配置<code>security.yml</code>文件. <code>security.yml</code>包含了应用安全组件的基本配置.<br>下面是能够使用FOSUserBundle的必须配置.<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"># app/config/security.yml</span><br><span class="line">security:</span><br><span class="line">    encoders:</span><br><span class="line">        FOS\UserBundle\Model\UserInterface: bcrypt</span><br><span class="line"></span><br><span class="line">    role_hierarchy:</span><br><span class="line">        ROLE_ADMIN:       ROLE_USER</span><br><span class="line">        ROLE_SUPER_ADMIN: ROLE_ADMIN</span><br><span class="line"></span><br><span class="line">    providers:</span><br><span class="line">        fos_userbundle:</span><br><span class="line">            id: fos_user.user_provider.username</span><br><span class="line"></span><br><span class="line">    firewalls:</span><br><span class="line">        main:</span><br><span class="line">            pattern: ^/</span><br><span class="line">            form_login:</span><br><span class="line">                provider: fos_userbundle</span><br><span class="line">                csrf_token_generator: security.csrf.token_manager</span><br><span class="line">                # if you are using Symfony &lt; 2.8, use the following config instead:</span><br><span class="line">                # csrf_provider: form.csrf_provider</span><br><span class="line"></span><br><span class="line">            logout:       true</span><br><span class="line">            anonymous:    true</span><br><span class="line"></span><br><span class="line">    access_control:</span><br><span class="line">        - &#123; path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY &#125;</span><br><span class="line">        - &#123; path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY &#125;</span><br><span class="line">        - &#123; path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY &#125;</span><br><span class="line">        - &#123; path: ^/admin/, role: ROLE_ADMIN &#125;</span><br></pre></td></tr></table></figure></p><p>在<code>providers</code>部分, 你通过<code>fos_userbundle</code>别名来使用FOSUserBundle中可用的的用户服务提供者.它的id是<code>fos_user.user_provider.username</code>.</p><p>下面我们来看<code>firewalls</code>部分. 这里我们申明了一个防火墙名为<code>main</code>. 通过指定<code>form_login</code>, 你需要告诉Symfony框架在任何时候的请求发送到这个防火墙时<br>都将引导用户进行认证, 不然用户将被重定向到一个表单页来输入他的凭证.</p><p>在<code>access_control</code>部分你可以指定用户在访问你应用中特殊的地址时所需要的凭证.bundle指定未认证用户能够在登录表单以及所有的路由中创建用户和重置密码.<br>这就是为什么你指定任何请求去匹配<code>/login</code>或者以<code>/register</code> 和 <code>/resetting</code>开头的地址时,将用户类型指定为匿名用户了.你肯定也注意到了, 任何以<code>/admin</code>开头的请求地址都需要用户为<code>ROLE_ADMIN</code>的身份.</p><p>更多关于<code>security.yml</code>文件的配置, 请查阅<a href="https://symfony.com/doc/current/book/security.html" target="_blank" rel="noopener">Symfony安全组件文档</a></p><blockquote><p>请注意我们在防火墙中配置的名称<code>main</code>, 你将在下一个步骤中使用它来配置FOSUserBundle.</p></blockquote><h3 id="步骤5-配置FOSUserBundle"><a href="#步骤5-配置FOSUserBundle" class="headerlink" title="步骤5:配置FOSUserBundle"></a>步骤5:配置FOSUserBundle</h3><p>现在我们配置的<code>security.yml</code>已经能够让FOSUserBundle正确的运行了, 接下来我们来为应用配置一些特定的需求.<br>根据你使用的数据库类型, 添加下面的配置信息到你的<code>config.yml</code>文件中.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># app/config/config.yml</span><br><span class="line">fos_user:</span><br><span class="line">    db_driver: orm # other valid values are &apos;mongodb&apos;, &apos;couchdb&apos; and &apos;propel&apos;</span><br><span class="line">    firewall_name: main</span><br><span class="line">    user_class: AppBundle\Entity\User</span><br></pre></td></tr></table></figure><p>仅需配置三个必须的配置项:</p><ul><li>你使用的数据库类型.(orm, mongodb, couchdb)</li><li>你在<a href="#步骤4-配置应用中的security-yml文件">步骤4</a>中配置的防火墙名字.</li><li>在<a href="#步骤3-创建你的用户类">步骤3</a>中创建的<code>User</code>类的全路径名.</li></ul><h3 id="步骤6-导入FOSUserBundle的路由文件"><a href="#步骤6-导入FOSUserBundle的路由文件" class="headerlink" title="步骤6:导入FOSUserBundle的路由文件"></a>步骤6:导入FOSUserBundle的路由文件</h3><p>现在你已经配置并且启用了整个bundle, 剩下的就是要导入所有的FOSUserBundle路由文件.<br>通过导入路由文件, 你将会生成一些现成的页面, 比如登录, 创建用户等等.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"># app/config/routing.yml</span><br><span class="line">fos_user:</span><br><span class="line">    resource: &quot;@FOSUserBundle/Resources/config/routing/all.xml&quot;</span><br></pre></td></tr></table></figure><blockquote><p>为了正常的使用内部的邮件功能(用于用户激活以及重置密码功能), 你必须配置并且启用了SwiftmailerBundle</p></blockquote><h3 id="步骤7-更新数据库的Schema"><a href="#步骤7-更新数据库的Schema" class="headerlink" title="步骤7:更新数据库的Schema"></a>步骤7:更新数据库的Schema</h3><p>至此, 整个bundle已经配置完毕, 因为在<a href="#步骤4-配置应用中的security-yml文件">步骤4</a>中你创建了<code>User</code>类并且添加了新的entity, 所以现在你要做的就是更新你的数据库Schema.<br>如果使用ORM,请执行下面命令.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ php bin/console doctrine:schema:update --force</span><br></pre></td></tr></table></figure><p>若使用的是MongoDB, 你则需要执行下面命令来创建索引.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ php bin/console doctrine:mongodb:schema:create --index</span><br></pre></td></tr></table></figure><p>现在你可以在<code>http://app.com/app_dev.php/login</code>地址中登录了.</p><p><strong>下一步</strong><br>现在你已经完成了FOSUserBundle的基本安装与配置, 可以了解一些更高级的特性.<br>比如下面这些可用的文档:<br><a href="/2016/09/28/overriding-default-fosuserbundle-templates/" title="重写FOSUserBundle的默认模板">重写FOSUserBundle的默认模板</a><br><a href="/2016/10/01/fosuserbundle-hooking-into-the-controller/" title="挂载到控制器">挂载到控制器</a><br><a href="/2016/10/04/fosuserbundle-overriding-default-controllers/" title="重写FOSUserBundle的默认控制器">重写FOSUserBundle的默认控制器</a><br><a href="/2016/10/07/fosuserbundle-overriding-default-forms/" title="重写FOSUserBundle的默认表单">重写FOSUserBundle的默认表单</a><br><a href="/2016/10/09/about-fosuserbundle-user-manager/" title="关于FOSUserBundle的用户管理服务">关于FOSUserBundle的用户管理服务</a><br><a href="/2016/10/11/fosuserbundle-command-line-tools/" title="FOSUserBundle命令行管理工具">FOSUserBundle命令行管理工具</a><br><a href="/2016/10/12/fosuserbundle-logging-by-username-or-email/" title="FOSUserBundle之使用用户名或密码登录">FOSUserBundle之使用用户名或密码登录</a><br><a href="/2016/10/12/fosuserbundle-username-form-type/" title="FOSUserBundle用户名表单字段">FOSUserBundle用户名表单字段</a><br><a href="/2016/10/14/fosuserbundle-emails/" title="FOSUserBundle的邮件服务">FOSUserBundle的邮件服务</a><br><a href="#">使用FOSUserBundle进行分组</a>(待翻译)</p>]]></content>
    
    <summary type="html">
    
      &lt;blockquote&gt;
&lt;p&gt;原文地址: &lt;a href=&quot;http://symfony.com/doc/current/bundles/FOSUserBundle/index.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://symfony.com/doc/current/bundles/FOSUserBundle/index.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Symfony的安全组件为你提供了一个灵活的框架, 它允许你从配置文件, 数据库, 或者其他任何你想象的到的地方来加载用户. FOSUserBundle则建立在此基础上, 更方便快速的将用户信息存储到数据库之中.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;准备工作&lt;/strong&gt;&lt;br&gt;1.3.x版本的FOSUserBundle依赖于Symfony2.1+. 如果你使用的是Symfony2.0.x, 请使用1.2.x系列的版本.&lt;/p&gt;
    
    </summary>
    
      <category term="外文翻译" scheme="http://yoursite.com/categories/%E5%A4%96%E6%96%87%E7%BF%BB%E8%AF%91/"/>
    
    
      <category term="翻译" scheme="http://yoursite.com/tags/%E7%BF%BB%E8%AF%91/"/>
    
      <category term="PHP" scheme="http://yoursite.com/tags/PHP/"/>
    
      <category term="Symfony" scheme="http://yoursite.com/tags/Symfony/"/>
    
      <category term="FOSUserBundle" scheme="http://yoursite.com/tags/FOSUserBundle/"/>
    
  </entry>
  
  <entry>
    <title>使用PhpStorm在vagrant环境下配置phpunit进行单元测试</title>
    <link href="http://yoursite.com/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/"/>
    <id>http://yoursite.com/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/</id>
    <published>2016-08-04T05:48:36.000Z</published>
    <updated>2016-08-04T09:33:46.000Z</updated>
    
    <content type="html"><![CDATA[<p>此文章主要介绍如何使用宿主机器中的PhpStorm配置vagrant环境中的phpunit来进行单元测试.</p><h2 id="前期准备"><a href="#前期准备" class="headerlink" title="前期准备"></a>前期准备</h2><ul><li><p>将phpstorm跟项目所在的vagrant虚拟机做关联:<br>依次进入 <strong><em> Settings -&gt; Tools -&gt; Vagrant </em></strong></p><img src="/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-1.png" title="关联vagrant"><blockquote><p>注意配置好红框里面的本地vagrant环境变量以及对应的vagrant虚拟机目录</p></blockquote></li></ul><a id="more"></a><p>  然后就可以使用工具栏中的vagrant来管理对应的虚拟机了, 详见工具栏: <strong><em> Tools -&gt; Vagrant </em></strong></p>  <img src="/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-1-2.png" title="使用phpstorm管理vagrant"><ul><li><p>配置好phpstorm中的php解释器   <strong><em> 进入下面的页面添加php解释器 </em></strong></p><img src="/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-2-1.png" title="添加php解释器"><img src="/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-2-2.png" title="选择添加remote解释器"><img src="/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-2-3.png" title="设置vagrant虚拟机的php解释器"><img src="/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-2-5.png" title="设置宿主机与vagrant虚拟机之间的目录映射"><blockquote><p>注意设置好宿主机与vagrant虚拟机之间的目录映射关系.</p></blockquote><img src="/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-2-4.png" title="配置完全"><blockquote><p>配置完全之后, php的解释器就如上图所示, 注意将 <strong><em> PHP language level </em></strong> 与你配置的解释器版本对应好.</p></blockquote></li></ul><h2 id="配置PHPUnit"><a href="#配置PHPUnit" class="headerlink" title="配置PHPUnit"></a>配置PHPUnit</h2><ul><li><p>进入 <strong><em> Settings -&gt; Language &amp; Frameworks -&gt; PHP -&gt; PHPUnit </em></strong> 远程PHPUnit解释器</p><img src="/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-3-1.png" title="配置远程PHPUnit解释器"><img src="/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-3-2.png" title="选择刚才配置的远程PHP解释器"><img src="/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-3-3.png" title="配置PHPUnit相关选项"><blockquote><p>注意选好对应的PHPUnit类库, 通常是选择 <strong><em> Use custom autoloader </em></strong> 或者 <strong><em> phpunit.phar </em></strong></p><ul><li>选择 <strong><em>autoloader</em></strong> 的时候, 我们将对应的 <strong><em>path</em></strong> 设置成 <strong><em>vender</em></strong> 目录中的 <strong><em>autoloader.php</em></strong> 文件<br>并且在项目中使用 <strong><em>composer</em></strong> 安装好相应的 <strong><em>PHPUnti</em></strong> 扩展即可.</li><li>选择 <strong><em>phpunit.phar</em></strong> 需将 <strong><em>Path</em></strong> 设置为 <strong><em>vagrant</em></strong> 虚拟机中安装好的 <strong><em>PHPUnit</em></strong> 扩展路径.</li></ul></blockquote></li></ul><h2 id="配置测试目录"><a href="#配置测试目录" class="headerlink" title="配置测试目录"></a>配置测试目录</h2>  <img src="/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-4-1.png" title="编辑测试配置"><blockquote><p>点击工具栏 <strong><em> Run -&gt; Edit Configuration </em></strong> 进行相应配置</p></blockquote>  <img src="/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-4-2.png" title="添加PHPUnit配置"><blockquote><p>添加PHPUnit配置</p></blockquote>  <img src="/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-4-3.png" title="配置PHPUnit相关选项"><blockquote><p>设置好要测试的文件夹或者文件</p></blockquote>  <img src="/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-4-4.png" title="点击执行测试">  <img src="/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-4-5.png" title="执行完毕的结果"><blockquote><h3 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h3><p><a href="https://phpunit.de/manual/current/zh_cn/installation.html" target="_blank" rel="noopener">PHPUnit手册</a><br><a href="https://confluence.jetbrains.com/display/PhpStorm/Testing+PHP+Applications" target="_blank" rel="noopener">PhpStorm中测试应用</a><br><a href="https://confluence.jetbrains.com/display/PhpStorm/Getting+started+with+Vagrant+in+PhpStorm" target="_blank" rel="noopener">在PhpStorm中管理vagrant</a><br><a href="https://confluence.jetbrains.com/display/PhpStorm/Running+PHPUnit+tests+over+SSH+on+a+remote+server+with+PhpStorm#RunningPHPUnittestsoverSSHonaremoteserverwithPhpStorm-PHPUnit" target="_blank" rel="noopener">使用PhpStorm在远程服务器上执行PHPUnit测试</a><br><a href="http://symfony.com/doc/current/testing.html" target="_blank" rel="noopener">Symfony测试文档</a></p></blockquote>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;此文章主要介绍如何使用宿主机器中的PhpStorm配置vagrant环境中的phpunit来进行单元测试.&lt;/p&gt;
&lt;h2 id=&quot;前期准备&quot;&gt;&lt;a href=&quot;#前期准备&quot; class=&quot;headerlink&quot; title=&quot;前期准备&quot;&gt;&lt;/a&gt;前期准备&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;将phpstorm跟项目所在的vagrant虚拟机做关联:&lt;br&gt;依次进入 &lt;strong&gt;&lt;em&gt; Settings -&amp;gt; Tools -&amp;gt; Vagrant &lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;img src=&quot;/2016/08/04/phpunit-test-in-phpstorm-and-vagrant/step-1.png&quot; title=&quot;关联vagrant&quot;&gt;
&lt;blockquote&gt;
&lt;p&gt;注意配置好红框里面的本地vagrant环境变量以及对应的vagrant虚拟机目录&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
    
    </summary>
    
      <category term="PHP" scheme="http://yoursite.com/categories/PHP/"/>
    
    
      <category term="PHP" scheme="http://yoursite.com/tags/PHP/"/>
    
      <category term="PhpStorm" scheme="http://yoursite.com/tags/PhpStorm/"/>
    
      <category term="Vagrant" scheme="http://yoursite.com/tags/Vagrant/"/>
    
      <category term="测试" scheme="http://yoursite.com/tags/%E6%B5%8B%E8%AF%95/"/>
    
  </entry>
  
  <entry>
    <title>使用Webpack 构建AngularJs的开发环境</title>
    <link href="http://yoursite.com/2016/06/17/bundling-angular-with-webpack/"/>
    <id>http://yoursite.com/2016/06/17/bundling-angular-with-webpack/</id>
    <published>2016-06-17T07:42:59.000Z</published>
    <updated>2016-06-21T01:12:37.000Z</updated>
    
    <content type="html"><![CDATA[<p>最终我们的工程目录结构:</p><a id="more"></a><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">project/</span><br><span class="line">--app/</span><br><span class="line">----controllers/</span><br><span class="line">------dashboard.controller.js</span><br><span class="line">----directives/</span><br><span class="line">------yep-nope.directive.js</span><br><span class="line">----services/</span><br><span class="line">------github-status.service.js</span><br><span class="line">----app.js</span><br><span class="line">--js/</span><br><span class="line">----angular.min.js</span><br><span class="line">--index.html</span><br></pre></td></tr></table></figure><ul><li><p>步骤一<br>  为了达到减少网络请求的目的, 我们希望最终的html文件里面仅存在两个js文件 <code>vendor.bundle.js</code> 和<br>  <code>app.bundle.js</code> 所以咱们可以现在 index.html页面里面引入这两个js文件, 例如:</p><pre><code>&lt;script src=&apos;js/vendor.bundle.js&apos;&gt;&lt;/script&gt;&lt;script src=&apos;js/app.bundle.js&apos;&gt;&lt;/script&gt;</code></pre></li><li><p>步骤二: 安装依赖<br>进入项目目录, 进行npm的初始化, 在终端键入 <code>npm init -y</code><br>安装必须的依赖包</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install angular webpack --save-dev</span><br></pre></td></tr></table></figure></li><li><p>步骤三: 配置webpack<br>  在你的项目根目录创建 <code>webpack.config.js</code> 文件<br>  内容如下:</p>  <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> webpack = <span class="built_in">require</span>(<span class="string">'webpack'</span>);</span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">context: __dirname + <span class="string">'/app'</span>,</span><br><span class="line">entry: &#123;</span><br><span class="line">app: <span class="string">'./app.js'</span>,</span><br><span class="line">vendor: [<span class="string">'angular'</span>]</span><br><span class="line">&#125;,</span><br><span class="line">output: &#123;</span><br><span class="line">path: __dirname + <span class="string">'/js'</span>,</span><br><span class="line">filename: <span class="string">'app.bundle.js'</span></span><br><span class="line">&#125;,</span><br><span class="line">plugins: [</span><br><span class="line"><span class="keyword">new</span> webpack.optimize.CommonsChunkPlugin(<span class="string">"vendor"</span>, <span class="string">"vendor.bundle.js"</span>)</span><br><span class="line">]</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>  这个文件中主要包含三个关键点<code>context</code>, <code>entry</code>, 和 <code>output</code>.</p><ul><li>context: 项目源文件的绝对路径</li><li>entry: 你的angular应用的主文件. 在这个例子中, 我们设置了一个包含app和vendor键名的对象, 一边产生多个bundle文件.</li><li><p>output: 定义编译后的bundle的文件保存的路径以及文件名.</p><p>这里还有一个<strong>plugins</strong>选项. 他允许我们将一些第三方的库文件合并为一个js文件. <a href="https://webpack.github.io/docs/code-splitting.html#split-app-and-vendor-code" target="_blank" rel="noopener">更多配置</a></p></li></ul></li><li><p>步骤四: 引入模块<br>  如果此时你打包你的代码, webpack只会将<strong>app.js</strong>中的代码打包起来. 那是因为我们并没有在<strong>app.js</strong>里面引入其他代码.<br>  接下来你可以引入任何你需要的代码就像这样:</p>  <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// app.js</span></span><br><span class="line">...</span><br><span class="line"><span class="built_in">require</span>(<span class="string">'./directives/yep-nope.controller'</span>);</span><br><span class="line"><span class="built_in">require</span>(<span class="string">'./services/github-status.service'</span>);</span><br><span class="line"><span class="built_in">require</span>(<span class="string">'./controllers/dashboard.controller'</span>);</span><br></pre></td></tr></table></figure><p>  在一些小的项目里面可以这么做, 但在大型的项目中, 这样做并不合适.</p><p>  相比在文件中直接引入一些控制器文件, 我们可以在controllers文件夹内创建一个<strong>index.js</strong>文件. 这个文件将为我们引入所有控制器的入口:</p>  <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> angular = <span class="built_in">require</span>(<span class="string">'angular'</span>);</span><br><span class="line"></span><br><span class="line">angular.module(<span class="string">'dashboard'</span>)</span><br><span class="line">.controller(<span class="string">'dashboardController'</span>, <span class="built_in">require</span>(<span class="string">'./dashboard.controller'</span>));</span><br></pre></td></tr></table></figure><p>  现在你controller文件夹下面的控制器文件看起来应该是像这样的:</p>  <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line">DashboardController.$inject = [<span class="string">'GithubStatusService'</span>];</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">DashboardController</span>(<span class="params">gh</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> _this = <span class="keyword">this</span>;</span><br><span class="line">    _this.github = <span class="string">''</span>;</span><br><span class="line">    gh.getStatus().success(<span class="function"><span class="keyword">function</span>(<span class="params">status</span>) </span>&#123;</span><br><span class="line">        _this.github = status;</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">module</span>.exports = DashboardController;</span><br></pre></td></tr></table></figure><p>  同样, 在directives文件夹中我们也可以这么做. 创建一个<strong>index.js</strong>文件来引导所有的指令. directives文件夹下的<strong>index.js</strong>文件可以这么写</p>  <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> angular = <span class="built_in">require</span>(<span class="string">'angular'</span>);</span><br><span class="line"></span><br><span class="line">angular.module(<span class="string">'dashboard'</span>).directive(<span class="string">'yepNope'</span>, <span class="built_in">require</span>(<span class="string">'./yep-nope.directive'</span>));</span><br></pre></td></tr></table></figure><p>  services目录下的<strong>index.js</strong>文件</p>  <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> angular = <span class="built_in">require</span>(‘angular’);</span><br><span class="line"></span><br><span class="line">angular.module(‘dashboard’).service(‘GithubStatusService’, <span class="built_in">require</span>(‘./github-status.service’));</span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = GithubStatusService;</span><br></pre></td></tr></table></figure><blockquote><p>最后一行应该是 <code>module.exports = GithubStatusService;</code></p></blockquote><p>  最终我们的<strong>app.js</strong>文件仅有这些:</p>  <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// app.js</span></span><br><span class="line">...</span><br><span class="line"><span class="built_in">require</span>(<span class="string">'./directives'</span>);</span><br><span class="line"><span class="built_in">require</span>(<span class="string">'./services'</span>);</span><br><span class="line"><span class="built_in">require</span>(<span class="string">'./controllers'</span>);</span><br></pre></td></tr></table></figure><p>  当你的应用越来越大的时候, 你需要添加新的<code>directives</code>,  <code>services</code> , 以及 <code>controllers</code> 你仅需要在<strong>directives/index.js</strong> <strong>services/index.js</strong>, 或者  <strong>controllers/index.js</strong> 中添加你要引入的文件.</p><p>  OK, 我们的angular应用已经准备好了. 接下来就是使用webpack来进行打包了.</p></li><li><p>步骤五: 配置任务<br>  我们在根目录下的 <strong>package.json</strong> 文件中的<code>script</code> 选项中添加任务, 然他来执行webpack, 就像这样.</p>  <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">"scripts"</span>: &#123;</span><br><span class="line"><span class="string">"test"</span>: <span class="string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>,</span><br><span class="line"><span class="string">"bundle"</span>: <span class="string">"webpack"</span></span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure><p>  在终端中, 你输入命令: <code>npm run bundle</code></p><p>  稍等片刻, 打包完毕之后你会看见:</p>  <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">angular-webpack@1.0.0 bundle /Users/ken/Projects/angular-webpack</span><br><span class="line">webpack</span><br><span class="line"></span><br><span class="line">Hash: fa17ee9ecec0b19a73ae</span><br><span class="line">Version: webpack 1.12.12</span><br><span class="line">Time: 550ms</span><br><span class="line">Asset Size Chunks Chunk Names</span><br><span class="line">app.bundle.js 1.42 kB 0 [emitted] app</span><br><span class="line">vendor.bundle.js 1.12 MB 1 [emitted] vendor</span><br><span class="line">[0] ./app.js 82 bytes &#123;0&#125; [built]</span><br><span class="line">[0] multi vendor 28 bytes &#123;1&#125; [built]</span><br><span class="line">[1] ./services/index.js 145 bytes &#123;0&#125; [built]</span><br><span class="line">[4] ./services/github-status.service.js 373 bytes &#123;0&#125; [built]</span><br><span class="line">[5] ./controllers/index.js 147 bytes &#123;0&#125; [built]</span><br><span class="line">[6] ./controllers/dashboard.controller.js 278 bytes &#123;0&#125; [built]</span><br><span class="line">+ 2 hidden modules</span><br></pre></td></tr></table></figure><p>  在浏览器中运行应用</p><pre><code>&gt;&gt; open index.html</code></pre></li></ul><p>基于webpack的angular开发环境就搭建结束.</p><blockquote><p><a href="http://blog.teamtreehouse.com/26017-2" target="_blank" rel="noopener">原文链接</a><br>翻译水平有限, 如果有看不懂的地方, 可以直接查看<a href="https://github.com/kenhowardpdx/angular-webpack" target="_blank" rel="noopener">项目源码</a></p></blockquote>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;最终我们的工程目录结构:&lt;/p&gt;
    
    </summary>
    
      <category term="外文翻译" scheme="http://yoursite.com/categories/%E5%A4%96%E6%96%87%E7%BF%BB%E8%AF%91/"/>
    
    
      <category term="Javascript" scheme="http://yoursite.com/tags/Javascript/"/>
    
      <category term="AngularJs" scheme="http://yoursite.com/tags/AngularJs/"/>
    
      <category term="翻译" scheme="http://yoursite.com/tags/%E7%BF%BB%E8%AF%91/"/>
    
  </entry>
  
  <entry>
    <title>Javascript 面向对象之继承的实现</title>
    <link href="http://yoursite.com/2016/05/20/javascript-extends-demo/"/>
    <id>http://yoursite.com/2016/05/20/javascript-extends-demo/</id>
    <published>2016-05-20T02:53:37.000Z</published>
    <updated>2016-05-20T02:58:20.000Z</updated>
    
    <content type="html"><![CDATA[<p>Javascript 里面实现继承的代码</p><p>示例代码:</p><a id="more"></a><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">//定义Persion 类</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Persion</span>(<span class="params">name, age</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.name = name;</span><br><span class="line">    <span class="keyword">this</span>.age = age;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">Persion.prototype.hi = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">"Hi my name is "</span> + <span class="keyword">this</span>.name + <span class="string">", I'm "</span> + <span class="keyword">this</span>.age + <span class="string">' years old now.'</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">Persion.prototype.LEGS_NUM = <span class="number">2</span>;</span><br><span class="line">Persion.prototype.ARMS_NUM = <span class="number">2</span>;</span><br><span class="line">Persion.prototype.walk = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="keyword">this</span>.name + <span class="string">" is walking..."</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//定义Student 类</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Student</span>(<span class="params">name, age, className</span>)</span>&#123;</span><br><span class="line">Persion.call(<span class="keyword">this</span>, name, age);</span><br><span class="line"><span class="keyword">this</span>.className = className;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//将Student类的原型指向Persion的原型</span></span><br><span class="line">Student.prototype = <span class="built_in">Object</span>.create(Persion.prototype);</span><br><span class="line">Student.prototype.constructor = Student;</span><br><span class="line"></span><br><span class="line"><span class="comment">//复写Persion中的hi 方法</span></span><br><span class="line">Student.prototype.hi = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">"Hi my name is "</span> + <span class="keyword">this</span>.name + <span class="string">", I'm "</span> + <span class="keyword">this</span>.age + <span class="string">" years old now, and from "</span> + <span class="keyword">this</span>.className + <span class="string">"."</span> );</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//定义Student中的learn 方法</span></span><br><span class="line">Student.prototype.learn = <span class="function"><span class="keyword">function</span>(<span class="params">subject</span>)</span>&#123;</span><br><span class="line"><span class="built_in">console</span>.log(<span class="keyword">this</span>.name + <span class="string">" is learning "</span> + subject + <span class="string">" at "</span> + <span class="keyword">this</span>.className);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//实例化Student类</span></span><br><span class="line"><span class="keyword">var</span> jack = <span class="keyword">new</span> Student(<span class="string">"Jack"</span>, <span class="number">27</span>, <span class="string">'Class 3, Greade 2'</span>);</span><br><span class="line"></span><br><span class="line">jack.hi();<span class="comment">//Hi, my name is Jack, I'm 27 years old now, and from Class 3, Greade 2.</span></span><br><span class="line">jack.LEGS_NUM;<span class="comment">// 2</span></span><br><span class="line">jack.ARMS_NUM;<span class="comment">// 2</span></span><br><span class="line">jack.learn(<span class="string">'math'</span>)  <span class="comment">// Jack is learning math at Class 3, Greade 2.</span></span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Javascript 里面实现继承的代码&lt;/p&gt;
&lt;p&gt;示例代码:&lt;/p&gt;
    
    </summary>
    
      <category term="代码" scheme="http://yoursite.com/categories/%E4%BB%A3%E7%A0%81/"/>
    
    
      <category term="Javascript" scheme="http://yoursite.com/tags/Javascript/"/>
    
      <category term="Demo" scheme="http://yoursite.com/tags/Demo/"/>
    
  </entry>
  
  <entry>
    <title>Drupal7模块开发 编写自动测试</title>
    <link href="http://yoursite.com/2016/03/23/drupal-module-development-2/"/>
    <id>http://yoursite.com/2016/03/23/drupal-module-development-2/</id>
    <published>2016-03-23T15:34:41.000Z</published>
    <updated>2016-05-20T02:59:59.000Z</updated>
    
    <content type="html"><![CDATA[<p>在代码结构里面,有这许多种类的测试.其中两种是最受欢迎的, <em>单元测试</em> 和 <em>功能测试</em>.</p><p>单元测试是专注于那些不连续的代码.  在面向对象的代码里,单元测试的重点是在一个对象里面的每个方法上. 在程序代码中,单元测试专注于函数,甚至偶尔在全局变量中.  其目的仅仅是为了去确认每个单元都能按照预期的职责去运行.</p><p>大多数为Drupal编写的测试都不是单元测试.相反,他们是一些功能测试. 也就是说, 测试是为了验证在Drupal中插入的代码是否与预期的功能一样,并且与其他代码相吻合.  这是一个比单元测试更广泛的测试种类.  测试可以精确的测量更大的代码块的准确性.</p><p>测试模块已经默认包含在Drupal7中,但是他是没有被默认启用的.一旦他启用了,你就可以在   Configuration-&gt;Development 找到Testing的配置页面.</p><p>测试应该存在自己的文件中,就像模块的主代码存放在 <code>modulename/modulename.module</code>之中一样,测试文件也应该在<br><code>modulename/modulename.test</code>中,这样测试框架变会自动去检索到它</p><a id="more"></a><h2 id="起步"><a href="#起步" class="headerlink" title="起步:"></a>起步:</h2><p>就像在模块里的其他文件一样,测试文件也必须被写在<code>.info</code>文件当中.所有我们需要加入的文件都必须填写在 <code>.info</code>文件里面的 <code>files</code> 数组之中.</p><pre><code>;$Id$name = Firstdescription = A first module.core = 7.xpackage = Drupal 7 Developmentfiles[] = first.modulefiles[] = first.test</code></pre><p>每当你的模块安装了之后,Drupal都会去缓存<code>.info</code>文件里面的内容.一旦你在<code>.info</code>文件里面添加了一个新的项目,你就必须去重新访问一下Drupal的模块页面,来强制Drupal重新解析<code>.info</code>文件.<br>(保险起见,这里建议 进入 Configuration-&gt;Development-&gt;Performance 中Clear all caches)</p><h2 id="编写测试部件"><a href="#编写测试部件" class="headerlink" title="编写测试部件:"></a>编写测试部件:</h2><p>大多数部件遵循下面这个简单的样本:</p><ol><li>创建一个继承DrupalWebTestCase 类</li><li>添加一个getInfo() 函数</li><li>在setUp() 方法里面设置一些必要的配置</li><li>以单词test开始来编写一些方法</li><li>在每个测试方法中,为测试的实际值来使用一个或多个声明</li></ol><p>当我们在进行我们自己的测试的时候,我们将按照上面的每一步来测试.</p><pre><code>&lt;?php/*** @file* Tests for the first module*/class FirstTestCase extends DrupalWebTestCase {// Methods will go here.}</code></pre><p>这个测试部件继承了一个叫做 DrupalWebTestCase的基类. 这个基类为测试提供了许多工具.测试案例不必要陈列或者使用核心逻辑.<br>出于这两种原因,每个Drupal测试必须继承这个基类,或者继承另外一个继承了这个基类的其他类.<br>一旦我们声明了这个类,我们就可以创建我们的第一个方法,<code>getInfo()</code>.</p><blockquote><p>命名约定与类<br>Drupal的function命名都是以小写字母命名的,并且用下划线来分割单词,但是类和方法的命名却不是这样的.类的命名应该以大写字母开头的驼峰式写法,例如”CamelCase”,方法的命名则是以小写字母开头的驼峰试写法,例如 “camelCase”.下划线是不允许出现在类与类方法的名称当中的.</p></blockquote><p>在之前,我们已经看到Drupal使用一些嵌套的数组来传递信息.例如我们之前创建的 <code>first_block_info()</code> 方法就是这样做的.<br>在<code>DrupalWebTestCase::getInfo()</code> 方法里面,同样也是返回一个关联数组.此时返回的信息就是关于这个测试的.</p><pre><code>&lt;?php/** * @file * Tests for the first module */class FirstTestCase extends DrupalWebTestCase {    public function setUp() {      parent::setUp(&apos;first&apos;);    }    public static function getInfo() {      return array(        &apos;name&apos; =&gt; &apos;First module block functionality&apos;,        &apos;description&apos; =&gt; &apos;Test blocks in the First module&apos;,        &apos;group&apos; =&gt; &apos;First&apos;,      );    }}</code></pre><p>这个<code>getInfo()</code>方法返回的是一个带有三个项目的数组,这三个项目分别是:</p><ol><li>name: 测试的名称</li><li>description:关于这个测试的一句话描述</li><li>grup:这个测试所属于的组</li></ol><p>这三个项目都是旨在为人类所读取的信息.  前面两个是纯粹的参考信息,第三个是将类似的测试罗列在相同的标题下.<br><code>getInfo()</code>函数看上去是不起眼的,但你的测试必须得包含他,也就是说,如果没有这个函数,你的测试将无法被执行 .</p><h2 id="设置测试"><a href="#设置测试" class="headerlink" title="设置测试:"></a>设置测试:</h2><pre><code>&lt;?php/*** @file* Tests for the first module*/class FirstTestCase extends DrupalWebTestCase {  public function setUp() {    parent::setUp(&apos;first&apos;);  }  public function getInfo() {    return array(      &apos;name&apos; =&gt; &apos;First module block functionality&apos;,      &apos;description&apos; =&gt; &apos;Test blocks in the First module.&apos;,      &apos;group&apos; =&gt; &apos;First&apos;,    );  }}</code></pre><p><code>setUp()</code>方法不是必须的,但当你一旦使用他的时候,你就必须写一行上述代码,就是如下:</p><pre><code>parent::setUp(&apos;first&apos;);</code></pre><p>这是告诉<code>setUp()</code>方法去启用存在于<code>DrupalWebTestCase</code>类里面的<code>setUp()</code>方法.<br>这么做的目的,是为了去初始化我们要测试的模块,这也意味着我们不需要去启动我们的模块,来进行测试代码的编写.<br>当你在编写你的测试部件的时候,你也可以在<code>parent::setUp()</code>请求下方编写你自己的配置信息,在之后我们将看到相关例子.</p><h2 id="编写测试方法"><a href="#编写测试方法" class="headerlink" title="编写测试方法:"></a>编写测试方法:</h2><p>测试部件的大多数的方法是测试方法,他们仅仅是用来验证模块是否正常工作.就像你看到的一样,没有任何代码中调用了这些方法.<br>那么简单测试是如何调用我们的方法呢?就像Drupal的钩子约定一样,任何以test开头的方法是会被测试框架自动执行.</p><pre><code>&lt;?php/** * @file * Tests for the first module */class FirstTestCase extends DrupalWebTestCase {    public function setUp() {      parent::setUp(&apos;first&apos;);    }    public static function getInfo() {      return array(        &apos;name&apos; =&gt; &apos;First module block functionality&apos;,        &apos;description&apos; =&gt; &apos;Test blocks in the First module&apos;,        &apos;group&apos; =&gt; &apos;First&apos;,      );    }    public function testBlockInfo() {      $info = module_invoke(&apos;first&apos;, &apos;block_info&apos;);      $this-&gt;assertEqual(1, count($info),        t(&apos;Module define a block.&apos;));      $this-&gt;assertTrue(isset($info[&apos;list_modules&apos;]),        t(&apos;Module list exists.&apos;));    }    public function testBlockView() {      $data = module_invoke(&apos;first&apos;, &apos;block_view&apos;,&apos;list_modules&apos;);      $this-&gt;assertTrue(is_array($data),        t(&apos;Block returns readerable array.&apos;));      $this-&gt;assertEqual(t(&apos;Enabled Modules&apos;), $data[&apos;subject&apos;],        t(&apos;Subject is set&apos;));    }}</code></pre><p>上面的代码包含了两个测试的成员方法,就像他们的名字一样,每个方法都是负责之前创建的两个区块方法的测试.<br>他们做了三个事情:<br>首先,他运行了一个叫做 <code>module_invoke()</code>的函数,并且用<code>$info</code>来存储了他的结果.<code>module_invoke()</code>函数主要是用来请求特定的模块里面的特定的钩子. <code>module_invoke()</code>方法有两个参数: 模块的名称,钩子的名称. 类似与<code>module_invoke(&#39;first&#39;,&#39;block_info&#39;)</code>这样的请求就好比在请求<code>first_block_info()</code>钩子,这样做的好处就是能确保他被钩子系统所挂载.为达到我们的预期,我们做了一个成对的断言. 测试框架会有效的验证这些断言,如果方法正如预期,则通过,否则失败.<br>我们先看看 <code>first_block_info()</code> 测试方法<br>这里做了两个测试:</p><pre><code>$this-&gt;assertEqual(1, count($info),  t(&apos;Module defines a block.));$this-&gt;assertTrue(isset($info[&apos;list_modules&apos;]),  t(&apos;Module list exists.&apos;));</code></pre><p>(注意,这些代码都为了格式化,把一行分割成了两行)</p><p>每个断言都有<code>$this-&gt;assertSOMETHING($conditions,$message)</code> 这样的格式,其中 <code>SOMETHING</code>表示断言的种类,<code>$conditions</code> 是断言满足并且可以通过的条件,<code>$message</code>就是一个测试的描述. 在我们的第一个测试中,<code>1</code> 与 <code>count($info)</code> 应该是相等的.断言方法都存在于 <code>DrupalWebTestCase</code>这个父类当中,这个类提供了十几种断言方法来使测试进行的更简单.</p><p>在例子中我们的断言是这样的:</p><ul><li>$this-&gt;assertEqual():第一个值(已知)等于第二值(测试值)的断言.</li><li>$this-&gt;assertTrue():给定结果为TRUE的断言.<br>第一个断言验证了我们在block_info()钩子里面定义的block,第二个断言验证了这个block的名字是否为list_modules.<br>这样,当我们的测试进行的时候,我们就可以确定我们的info钩子是否返回了关于我们的简单的区块的信息.</li></ul><p>再看看<code>first_block_view()</code>的测试.</p><pre><code>public function testBlockView() {    $data = module_invoke(&apos;first&apos;, &apos;block_view&apos;,        &apos;list_modules&apos;);    $this-&gt;assertTrue(is_array($data),        t(&apos;Block returns renderable array.&apos;));    $this-&gt;assertEqual(t(&apos;Enabled Modules&apos;), $data[&apos;subject&apos;],        t(&apos;Subject is set&apos;));}</code></pre><p>这次我们执行的是 <code>block_view()</code>钩子.并且再次执行了两个断言.第一个断言确认了<code>first_block_view()</code>返回的是否是一个数组.第二个断言验证了他的标题是否与我们预期的一样,为 <code>Enabled Modules</code>.</p><p>编写完毕,我们就可以去 Configuration-&gt; Testing 里面去选中我们的测试,并且运行他了,看看结果吧,你的测试是否都通过了呢!</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;在代码结构里面,有这许多种类的测试.其中两种是最受欢迎的, &lt;em&gt;单元测试&lt;/em&gt; 和 &lt;em&gt;功能测试&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;单元测试是专注于那些不连续的代码.  在面向对象的代码里,单元测试的重点是在一个对象里面的每个方法上. 在程序代码中,单元测试专注于函数,甚至偶尔在全局变量中.  其目的仅仅是为了去确认每个单元都能按照预期的职责去运行.&lt;/p&gt;
&lt;p&gt;大多数为Drupal编写的测试都不是单元测试.相反,他们是一些功能测试. 也就是说, 测试是为了验证在Drupal中插入的代码是否与预期的功能一样,并且与其他代码相吻合.  这是一个比单元测试更广泛的测试种类.  测试可以精确的测量更大的代码块的准确性.&lt;/p&gt;
&lt;p&gt;测试模块已经默认包含在Drupal7中,但是他是没有被默认启用的.一旦他启用了,你就可以在   Configuration-&amp;gt;Development 找到Testing的配置页面.&lt;/p&gt;
&lt;p&gt;测试应该存在自己的文件中,就像模块的主代码存放在 &lt;code&gt;modulename/modulename.module&lt;/code&gt;之中一样,测试文件也应该在&lt;br&gt;&lt;code&gt;modulename/modulename.test&lt;/code&gt;中,这样测试框架变会自动去检索到它&lt;/p&gt;
    
    </summary>
    
      <category term="外文翻译" scheme="http://yoursite.com/categories/%E5%A4%96%E6%96%87%E7%BF%BB%E8%AF%91/"/>
    
    
      <category term="翻译" scheme="http://yoursite.com/tags/%E7%BF%BB%E8%AF%91/"/>
    
      <category term="Drupal" scheme="http://yoursite.com/tags/Drupal/"/>
    
  </entry>
  
  <entry>
    <title>Drupal7模块开发 创建第一个模块</title>
    <link href="http://yoursite.com/2016/03/23/drupal-module-development-1/"/>
    <id>http://yoursite.com/2016/03/23/drupal-module-development-1/</id>
    <published>2016-03-23T14:00:16.000Z</published>
    <updated>2016-03-29T04:04:01.000Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>Drupal7模块开发 系列是 由 Drupal 7 Module Development 英文版翻译过来的, 主要用于学习drupal的模块开发. 至于翻译质量, 我只能说尽力了, 大家凑活看吧, 鄙人文字功底有限. 如果有些地方真的被我翻译到误人子弟的地步, 恳请大家指正.</p></blockquote><h2 id="模块命名"><a href="#模块命名" class="headerlink" title="模块命名"></a>模块命名</h2><p>Drupal的模块有两个名字,人读名与机读名.</p><blockquote><p>  人读名: 是由首字母大写的且用空格分开的单词组成,例如:Views, Eldorado Superfly等等.</p></blockquote><blockquote><p>  机读名: 是由小写字母,数字和下划线组成的字符串,且不允许有其他字母.例如上面两个模块的机读名字则应该为:views和eldorado_superfly.</p></blockquote><p>按照惯例这两个名字应该差不多,而且通常应该将大写祖母转化为小写字母.</p><a id="more"></a><h2 id="模块存放位置"><a href="#模块存放位置" class="headerlink" title="模块存放位置"></a>模块存放位置</h2><p>Drupal 的自定义模块通常是用来存放在 <code>/sites/default/modules</code> 文件夹下面, 这样做的好处是可以与标准模块分开,以便更容易找到自己没有整理的杂乱的代码.</p><p>Drupal中自定义模块如果放在 <code>/sites/default</code> 文件夹中, 只能被默认站点所加载. 这意味着, 在实践中如果把模块放在 <code>/sites/default/modules</code> 文件夹下,根本不会加载到其他站点中. 在这种情况下, 一般会建议把自定义模块放在<code>/sites/all/modules/custom</code> 这个文件夹下.</p><h2 id="创建模块文件夹"><a href="#创建模块文件夹" class="headerlink" title="创建模块文件夹"></a>创建模块文件夹</h2><p>模块可以以多种途径来进行组织, 但是实践证明, 最好的选择还是得将模块放在 <code>/sites/defualt/modules</code> 文件夹下,并且模块中至少得有两个文件<code>a.info</code>以及<code>a.module</code></p><p>文件夹,以及文件夹下的.info文件和.module文件,都必须以机读名的方式来命名. 且<code>.info</code>和<code>.module</code>文件只能被设定为只读模式</p><ul><li><p>编写.info文件<br><code>.info</code> 文件是为Drupal提供信息的文件. 其中的信息包括:模块人读名, 此模块所要请求的其他模块, 以及此模块提供了哪些代码文件.<br>一个<code>.info</code>文件是一个类似于<code>.ini</code>标准的控制文件. 在<code>.info</code>文件中的指令是由: 名称, 等号, 值.这三个元素组成的. 例如:</p><pre><code>name = value</code></pre><p>或者以数组的形式进行申明,例如:</p><pre><code>name[] = value1name[] = value2</code></pre><p>(注意,两个方括号中间没有空格)</p><p>drupal的编码规范中,在等号两端通常都有一个空格符号.<br>如果一个值的跨度超过一行, 那他应该被包含在一个括号之中.<br>在drupal的ini解释器中,任何以分号开头的代码都将作为注释,被忽略掉.</p></li><li><p>编写.module文件<br><code>.module</code> 文件一般是一个包含了模块所使用的主要的钩子的PHP文件.<br>下面是一个简单的help钩子的代码</p><pre><code><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// $Id$</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@file</span></span></span><br><span class="line"><span class="comment"> * A module exemplifying Drupal coding practices and APIs.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * This module provides a block that lists all of the</span></span><br><span class="line"><span class="comment"> * installed modules. It illustrates coding standards,</span></span><br><span class="line"><span class="comment"> * practices, and API use for Drupal 7.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment">  * Implements hook_help().</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">first_help</span><span class="params">($path, $arg)</span> </span>&#123;</span><br><span class="line">   <span class="keyword">if</span> ($path == <span class="string">'admin/help#first'</span>) &#123;</span><br><span class="line">     <span class="keyword">return</span> t(<span class="string">'A demonstration module.'</span>);</span><br><span class="line">   &#125;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure></code></pre><p>在上述代码中有以下代码规范:</p><ul><li>所有的PHP 和 Javascript文件的都使用两格空格来进行缩进, tab是不允许使用在任何代码里.</li><li>在一个完全的PHP文件代码中,通常是省略结尾部的结束标签代码 ‘?&gt;’. 这是要防止夹杂着的空白来打断HTTP的标头.</li><li>Drupal 是使用 Doxygen-styel风格来注释(/*<em> </em>/)方法,类,界面,常亮,文件,全局文件的. #号是不允许使用在注释之中的.</li><li>在运算符两边必须有一个空格的.</li><li>所有的控制流程代码都必须包括在大括号之内.即使if的控制流程代码只有一行主体代码,也是需要用大括号包裹起来.</li><li>方法的命名都是用小写字母以及下划线来分割单词.</li><li>变量名是使用小写字母以及下划线来分割单词之间的空格的.</li></ul></li><li><p>翻译函数 <code>t()</code> 和翻译<br>翻译函数必须遵循如下写法:</p><pre><code>t(&apos;This is my string&apos;);</code></pre><p>不能以下面的方式来写:</p><pre><code>$variable = &apos;This is a string&apos;;t($variable);</code></pre><p>这是因为t()函数, 他不执行代码, 只是读取代码.<br>t()函数接受一个可选参数，这是个关联数组. 例如:</p><pre><code>$values = array(&apos;@user&apos; =&gt; $username);print t(&apos;Welcome, @user&apos;, $values);</code></pre><p>这两行代码中,申明@user为占位符,值为变量<code>$username</code>的值.当<code>t()</code>函数被调用时, $values的映射将替换掉要被翻译语句中的占位符.<br>如果占位符使用@符号开头, 则Drupal将在插入翻译之前, 对这个值使用<code>check_plain()</code>方法来进行过滤.<br>如果你确定你的字符串没有任何危险,则可以使用感叹号(!)开头来命名占位符.但这样做,drupal将直接插入这个值,而不进行过滤.这在不需要对你要插入的数据进行翻译的时候,是非常有用的. 像这样写:</p><pre><code>$values = array(&apos;!url&apos; =&gt; &apos;http://example.com&apos;);print t(&apos;The website can be found at !url&apos;, $values);</code></pre><p>百分号开头的占位符,可以在值插入之前进行安全过滤,并且强制值为文本类型;(用em标签包围),像这样写:</p><pre><code>$values = array(&apos;%color&apos; =&gt; &apos;blue&apos;);print t(&apos;My favorite color is %color.&apos;, $values);</code></pre></li></ul><a href="/2016/03/23/drupal-module-development-2/" title="下一步 编写自动测试">下一步 编写自动测试</a>]]></content>
    
    <summary type="html">
    
      &lt;blockquote&gt;
&lt;p&gt;Drupal7模块开发 系列是 由 Drupal 7 Module Development 英文版翻译过来的, 主要用于学习drupal的模块开发. 至于翻译质量, 我只能说尽力了, 大家凑活看吧, 鄙人文字功底有限. 如果有些地方真的被我翻译到误人子弟的地步, 恳请大家指正.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;模块命名&quot;&gt;&lt;a href=&quot;#模块命名&quot; class=&quot;headerlink&quot; title=&quot;模块命名&quot;&gt;&lt;/a&gt;模块命名&lt;/h2&gt;&lt;p&gt;Drupal的模块有两个名字,人读名与机读名.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;  人读名: 是由首字母大写的且用空格分开的单词组成,例如:Views, Eldorado Superfly等等.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;  机读名: 是由小写字母,数字和下划线组成的字符串,且不允许有其他字母.例如上面两个模块的机读名字则应该为:views和eldorado_superfly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;按照惯例这两个名字应该差不多,而且通常应该将大写祖母转化为小写字母.&lt;/p&gt;
    
    </summary>
    
      <category term="外文翻译" scheme="http://yoursite.com/categories/%E5%A4%96%E6%96%87%E7%BF%BB%E8%AF%91/"/>
    
    
      <category term="翻译" scheme="http://yoursite.com/tags/%E7%BF%BB%E8%AF%91/"/>
    
      <category term="Drupal" scheme="http://yoursite.com/tags/Drupal/"/>
    
  </entry>
  
</feed>
