目录

用表关联结构实现类目管理

优质
小牛编辑
124浏览
2023-12-01

以终为始

想象一下我们希望有怎么样的分类,比如你是一个音乐爱好者,那么你的博客可能会分成:摇滚、流行、古典……;如果你是一个体育爱好者,那么可能会分成:篮球赛事、户外运动、健身……;如果是一个IT爱好者,可能会分成:大数据、数学知识、信息检索……。那么首先我们需要的是一个类目表。

创建src/AppBundle/Entity/Subject.php这个model,如下:

<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
 * Subject
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Subject
{
    /**
     * @ORM\OneToMany(targetEntity="BlogPost", mappedBy="subject")
     */
    private $blogPosts;
    public function __construct()
    {
        $this->blogPosts = new ArrayCollection();
    }
    public function getBlogPosts()
    {
        return $this->blogPosts;
    }
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;
/**
 * @var string
 *
 * @ORM\Column(name="name", type="string", length=255)
 */
private $name;
/**
 * @var string
 *
 * @ORM\Column(name="photo", type="string", length=255)
 */
private $photo;
/**
 * @var string
 *
 * @ORM\Column(name="introduce", type="string", length=255)
 */
private $introduce;
/**
 * @return string
 */
public function getIntroduce()
{
    return $this-&gt;introduce;
}
/**
 * @param string $introduce
 */
public function setIntroduce($introduce)
{
    $this-&gt;introduce = $introduce;
}
/**
 * Get id
 *
 * @return integer
 */
public function getId()
{
    return $this-&gt;id;
}
/**
 * Set name
 *
 * @param string $name
 * @return Subject
 */
public function setName($name)
{
    $this-&gt;name = $name;
    return $this;
}
/**
 * Get name
 *
 * @return string
 */
public function getName()
{
    return $this-&gt;name;
}
/**
 * Set photo
 *
 * @param string $photo
 * @return Subject
 */
public function setPhoto($photo)
{
    $this-&gt;photo = $photo;
    return $this;
}
/**
 * Get photo
 *
 * @return string
 */
public function getPhoto()
{
    return $this-&gt;photo;
}

}

这里的private $blogPosts;是一个一对多(OneToMany)的关系类型,@ORM声明了targetEntity="BlogPost", mappedBy="subject",表示$blogPosts只能存储BlogPost类型的数据,并且这些数据都是以BlogPost::subject来做hash的,那么就需要BlogPost必须有subject成员变量,下面我们来添加,修改src/AppBundle/Entity/BlogPost.php,添加:

    /**
     * @ORM\ManyToOne(targetEntity="Subject", inversedBy="blogPosts")
     */
    private $subject;

并添加get和set方法:

    public function setSubject(Subject $subject)
    {
        $this->subject = $subject;
    }
    public function getSubject()
    {
        return $this->subject;
    }

这里的private $subject;是一个多对一(ManyToOne)的关系类型,@ORM声明了targetEntity="Subject", inversedBy="blogPosts",表示$subject存储的是Subject类型的数据,并和Subject::blogPosts有对应关系

添加SubjectAdmin管理类,添加src/AppBundle/Admin/SubjectAdmin.php文件,内容如下:

<?php
namespace AppBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
class SubjectAdmin extends Admin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper->add('name', 'text')
            ->add('introduce', 'text')
            ->add('photo', 'text');
    }
    protected function configureDatagridFilters(DatagridMapper $datagridMapper)
    {
        $datagridMapper->add('name');
    }
    protected function configureListFields(ListMapper $listMapper)
    {
        $listMapper->addIdentifier('name')
            ->add('introduce')
            ->add('photo');
    }
}

执行如下语句来创建subject表和更新blogpost表:

[root@centos7vm mywebsite]# php app/console doctrine:schema:update --force

修改app/config/services.yml注册admin.subject服务,在services组添加:

    admin.subject:
        class: AppBundle\Admin\SubjectAdmin
        arguments: [~, AppBundle\Entity\Subject, ~]
        tags:
            - { name: sonata.admin, manager_type: orm, label: Subject }

这时打开http://172.16.142.130/app_dev.php/admin看到多出了subject的管理界面:

我们添加一个subject,如下:

保存后,看到我们生成了一个subject数据:

这里的photo先随便填一个,以后再用到这个字段

如果你打算新建一个blogpost来指定一个subject,那么会发现,在blogpost的编辑界面没有选择科目的地方,这时怎么办呢?我们还需要修改一下BlogPostAdmin管理类,修改src/AppBundle/Admin/BlogPostAdmin.php,如下:

        $formMapper
            ->add('title', 'text')
            ->add('body', 'ckeditor', array('autoload' => true))
            ->add('subject', 'sonata_type_model', array(
                'class' => 'AppBundle\Entity\Subject',
                'property' => 'name',
            ))
            ->add('create_time', 'sonata_type_date_picker', array(
                'format'=>'yyyy-MM-dd HH:mm:ss',
                'dp_default_date'        => date('Y-m-d H:i:s'),));

这时打开blogpost编辑界面看到:

多出了subject选择框

我们新建一篇看下:

列表中列出了这篇blog,但是没有看到类目呢?这是因为我们没有配置显示subject字段,继续修改src/AppBundle/Admin/BlogPostAdmin.php的configureListFields方法,内容如下:

        $listMapper
            ->addIdentifier('title')
            ->add('subject.name')
            ->add('createTime')
            ;

这时候再看blog列表:

成功啦

下面的任务就留给你自己:用同样的方式来添加category,用来表示另一个层级的分类,比如:原创、转载、学习笔记……,这样你的文章可以是:“大数据”类别下的“原创”文章。

提示一下:

第一步添加如下文件:src/AppBundle/Entity/Category.php、src/AppBundle/Admin/CategoryAdmin.php

第二步修改如下文件:src/AppBundle/Entity/BlogPost.php、src/AppBundle/Admin/BlogPostAdmin.php

第三步修改如下配置:app/config/services.yml

第四步更新数据库:php app/console doctrine:schema:update --force

最终效果如下:

添加博客页面

博客列表页面