{"id":233695,"date":"2014-08-18T13:27:03","date_gmt":"2014-08-18T09:27:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=233695"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=233695","title":{"rendered":"<span class=\"post_title\">\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0442\u0435\u0433\u043e\u0432 \u0432 \u0430\u0434\u043c\u0438\u043d\u043a\u0435 \u0441 \u0431\u0430\u043d\u0434\u043b\u043e\u043c SonataAdminBundle<\/span>"},"content":{"rendered":"<div class=\"content html_format\">     \t\u041c\u043d\u043e\u0433\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0431\u0430\u043d\u0434\u043b\u043e\u043c <a href=\"https:\/\/github.com\/sonata-project\/SonataAdminBundle\">SonataAdminBundle<\/a> \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0430 Symfony2. \u042d\u0442\u043e\u0442 \u0431\u0430\u043d\u0434\u043b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432 \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0435 \u0441\u0440\u043e\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c CRUD-\u0430\u0434\u043c\u0438\u043d\u043a\u0443 \u0434\u043b\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 Doctrine \u0438 Mongo. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u043b\u0435\u0433\u043a\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0438 \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0438\u043c\u0438 \u0441\u0432\u044f\u0437\u0438 \u041e\u0434\u0438\u043d-\u043a\u043e-\u041c\u043d\u043e\u0433\u0438\u043c \u0438 \u041c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u041c\u043d\u043e\u0433\u0438\u043c. \u0412\u043e\u0442 \u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u043f\u0443\u043d\u043a\u0442\u043e\u043c \u0443 \u043c\u0435\u043d\u044f \u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0442\u0435\u0433\u043e\u0432 \u0434\u043b\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044f \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u043d\u0443 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0430\u043d\u0434\u043b\u0430 <a href=\"http:\/\/knpbundles.com\/FabienPennequin\/FPNTagBundle\">FPNTagBundle<\/a>, \u0438 \u0447\u0442\u043e \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e\u0442 \u0431\u0430\u043d\u0434\u043b \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0432 SonataAdmin.<br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h4>\u041f\u0440\u043e\u0441\u0442\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0435\u0433\u043e\u0432<\/h4>\n<p>  \u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 (\u0443\u0441\u043b\u043e\u0432\u043d\u043e \u043d\u0430\u0437\u043e\u0432\u0451\u043c \u0438\u0445 Article \u0438 News, \u0445\u043e\u0442\u044f \u0432\u0441\u0435\u0433\u043e \u0438\u0445 \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0441\u0435\u043c\u044c), \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u0435\u0433\u0438, \u043f\u0440\u0438\u0447\u0451\u043c \u043e\u0434\u043d\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0433\u043e\u0432, \u0442\u043e \u0435\u0441\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0432\u044f\u0437\u044c \u041c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u041c\u043d\u043e\u0433\u0438\u043c. <br \/>  \u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0432\u043e\u0430\u043d\u0438\u0435 \u0442\u0435\u0433\u043e\u0432 \u0432 \u0430\u0434\u043c\u0438\u043d\u043a\u0435 \u0431\u0435\u0437 \u0431\u0430\u043d\u0434\u043b\u0430 FPNTagBundle. \u042f \u0441\u0434\u0435\u043b\u0430\u043b \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c, \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0411\u0430\u0437\u043e\u0432\u0430\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c Entity<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">namespace App\\AppBundle\\Entity;  use Doctrine\\ORM\\Mapping as ORM;  \/\/ \u043d\u0435\u0442 \u0442\u0435\u0433\u0430 ORM\\Entity - \u0434\u043e\u043a\u0442\u0440\u0438\u043d\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c\u044e \u0438 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 class Entity {     \/**      * @var integer      * @ORM\\Id      * @ORM\\Column(type=&quot;integer&quot;)      * @ORM\\GeneratedValue(strategy=&quot;AUTO&quot;)      *\/     protected $id;      \/**      * @var boolean      * @ORM\\Column(type=&quot;boolean&quot;, options={&quot;default&quot;:false})      *\/     protected $published = false;      \/**      * @var string      * @ORM\\Column(type=&quot;string&quot;, length=255)      *\/     protected $title;          \/**      * @var string      * @ORM\\Column(type=&quot;text&quot;)      *\/     protected $content;      \/\/ \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u044f           \/**      * Get id      * @return integer      *\/     public function getId()     {         return $this-&gt;id;     }      \/**      * Set published      * @param boolean $published      * @return Entity      *\/     public function setPublished($published)     {         $this-&gt;published = $published;         return $this;     }      \/**      * Toggle published      * @return Entity      *\/     public function togglePublished()     {         $this-&gt;published = !$this-&gt;published;         return $this;     }      \/**      * Get published      * @return boolean      *\/     public function getPublished()     {         return $this-&gt;published;     }          \/**      * Set title      * @param string $title      * @return Entity      *\/     public function setTitle($title)     {         $this-&gt;title = $title;         return $this;     }      \/**      * Get title      * @return string      *\/     public function getTitle()     {         return $this-&gt;title;     }      \/**      * Set content      * @param string $content      * @return Entity      *\/     public function setContent($content)     {         $this-&gt;content = $content;         return $this;     }      \/**      * Get content      * @return string      *\/     public function getContent()     {         return $this-&gt;content;     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0414\u0432\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u0443\u0449\u043d\u043e\u0441\u0442\u044c Article<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">namespace App\\AppBundle\\Entity;  use Doctrine\\ORM\\Mapping as ORM; use Doctrine\\Common\\Collections\\ArrayCollection;  \/**  * @ORM\\Table()  * @ORM\\Entity()  *\/ class Article extends Entity {     \/**      * @var ArrayCollection      * @ORM\\ManyToMany(targetEntity=&quot;Tag&quot;, inversedBy=&quot;articles&quot;)      * @ORM\\JoinTable(name=&quot;article_tags&quot;)      *\/     protected $tags;      \/**      * @return ArrayCollection      *\/     public function getTags()     {         return $this-&gt;tags ?: $this-&gt;tags = new ArrayCollection();     }      public function addTag(Tag $tag)     {         $tag-&gt;addArticle($this);         $this-&gt;tags[] = $tag;     }      public function removeTag(Tag $tag)     {         return $this-&gt;tags-&gt;removeElement($tag);     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u0443\u0449\u043d\u043e\u0441\u0442\u044c News<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">namespace App\\AppBundle\\Entity;  use Doctrine\\ORM\\Mapping as ORM; use Doctrine\\Common\\Collections\\ArrayCollection;  \/**  * @ORM\\Table()  * @ORM\\Entity()  *\/ class News extends Entity {     \/**      * @var \\DateTime      * @ORM\\Column(type=&quot;datetime&quot;, nullable=true)      *\/     protected $publishedAt;      \/**      * @var ArrayCollection      * @ORM\\ManyToMany(targetEntity=&quot;Tag&quot;, inversedBy=&quot;news&quot;)      * @ORM\\JoinTable(name=&quot;news_tags&quot;)      *\/     protected $tags;          \/**      * Set publishedAt      * @param \\DateTime $publishedAt      * @return News      *\/     public function setPublishedAt($publishedAt)     {         $this-&gt;publishedAt = $publishedAt;         return $this;     }      \/**      * Get publishedAt      * @return \\DateTime      *\/     public function getPublishedAt()     {         return $this-&gt;publishedAt;     }      \/**      * @return ArrayCollection      *\/     public function getTags()     {         return $this-&gt;tags ?: $this-&gt;tags = new ArrayCollection();     }      public function addTag(Tag $tag)     {         $tag-&gt;addArticle($this);         $this-&gt;tags[] = $tag;     }      public function removeTag(Tag $tag)     {         return $this-&gt;tags-&gt;removeElement($tag);     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0418 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0442\u0435\u0433\u043e\u0432:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u0443\u0449\u043d\u043e\u0441\u0442\u044c Tag<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">namespace App\\AppBundle\\Entity;  use Doctrine\\ORM\\Mapping as ORM; use Doctrine\\Common\\Collections\\ArrayCollection;  \/**  * @ORM\\Table()  * @ORM\\Entity()  *\/ class Tag {     public function __construct() {         $this-&gt;articles = new ArrayCollection();         $this-&gt;news = new ArrayCollection();     }      \/**      * @var integer $id      * @ORM\\Column(type=&quot;integer&quot;)      * @ORM\\GeneratedValue(strategy=&quot;AUTO&quot;)      * @ORM\\Id      *\/     protected $id;      \/**      * @var string      * @ORM\\Column(type=&quot;string&quot;, length=100)      *\/     protected $name;      \/**      * @ORM\\ManyToMany(targetEntity=&quot;Article&quot;, mappedBy=&quot;tags&quot;)      *\/     private $articles;      \/**      * @ORM\\ManyToMany(targetEntity=&quot;News&quot;, mappedBy=&quot;tags&quot;)      *\/     private $news;      public function addArticle(Article $article)     {         $this-&gt;articles[] = $article;     }      public function addNews(News $news)     {         $this-&gt;news[] = $news;     }          public function getArticles()     {         $this-&gt;articles;     }      public function getNews()     {         $this-&gt;news;     }          \/**      * @return integer      *\/     public function getId()     {         return $this-&gt;id;     }      \/**      * @param string $name      * @return Tag      *\/     public function setName($name)     {         $this-&gt;name = $name;          return $this;     }      \/**      * @return string      *\/     public function getName()     {         return $this-&gt;name;     }  } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u0434\u0432\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 Article \u0438 News \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0432 \u0441\u0432\u044f\u0437\u0438 Many-to-Many. \u0418 \u043d\u0430\u043b\u0438\u0447\u0438\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u0432 News, \u0447\u0442\u043e \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<p>  \u0412 \u0414\u043e\u043a\u0442\u0440\u0438\u043d\u0435 \u0441\u0432\u044f\u0437\u044c \u041c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u041c\u043d\u043e\u0433\u0438\u043c \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u043b\u0435\u0433\u043a\u043e, \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u043f\u0430\u0440\u044b \u0441\u0442\u0440\u043e\u0447\u0435\u043a \u0432 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438. \u0422\u0435, \u043a\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441 Doctrine, \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b\u0438 \u044d\u0442\u0443 \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u0443. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430. \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0432 \u0442\u0430\u043a\u0443\u044e \u0441\u0432\u044f\u0437\u044c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438, \u043b\u0435\u0433\u043a\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0435\u0433\u043e\u0432 \u0434\u043b\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0432 Sonata-\u0430\u0434\u043c\u0438\u043d\u043a\u0435:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0411\u0430\u0437\u043e\u0432\u0430\u044f \u0430\u0434\u043c\u0438\u043d\u043a\u0430 \u0434\u043b\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">namespace App\\AppBundle\\Admin;  use Sonata\\AdminBundle\\Admin\\Admin; use Sonata\\AdminBundle\\Datagrid\\ListMapper; use Sonata\\AdminBundle\\Datagrid\\DatagridMapper; use Sonata\\AdminBundle\\Form\\FormMapper;  \/\/ \u0418\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u043d\u0435 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 Admin, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 Sonata \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0435\u0451 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0430\u0434\u043c\u0438\u043d\u043a\u043e\u0439 class EntityAdminBase extends Admin {     protected function configureFormFields(FormMapper $formMapper)     {         $formMapper             -&gt;add('title', 'text')             -&gt;add('content', 'ckeditor')             -&gt;add('tags', 'entity', array(                 'class'=&gt;'AppBundle:Tag',                  'multiple' =&gt; true,                  'attr'=&gt;array('style'=&gt;'width: 100%;'))             )             \/\/ \u0441\u0442\u0438\u043b\u044c width: 100% \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0431\u0430\u0433\u0430 \u0443 Select2-\u043f\u043e\u043b\u044f,              \/\/ \u043a\u043e\u0433\u0434\u0430 \u0448\u0438\u0440\u0438\u043d\u0430 \u043f\u043e\u043b\u044f \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f, \u0438 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0442\u0435\u0433\u0438 \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e         ;     }          protected function configureDatagridFilters(DatagridMapper $datagridMapper)     {         $datagridMapper             -&gt;add('title')             -&gt;add('tags', null, array(), null, array('multiple' =&gt; true))         ;     }      protected function configureListFields(ListMapper $listMapper)     {         $listMapper             -&gt;addIdentifier('title')             -&gt;add('published')                         ;     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0410\u0434\u043c\u0438\u043d\u043a\u0430 Article<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">namespace App\\AppBundle\\Admin;  use Sonata\\AdminBundle\\Admin\\Admin; use Sonata\\AdminBundle\\Datagrid\\ListMapper; use Sonata\\AdminBundle\\Datagrid\\DatagridMapper; use Sonata\\AdminBundle\\Form\\FormMapper;  class ArticleAdmin extends EntityAdminBase {      } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0410\u0434\u043c\u0438\u043d\u043a\u0430 News<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">namespace App\\AppBundle\\Admin;  use Sonata\\AdminBundle\\Admin\\Admin; use Sonata\\AdminBundle\\Datagrid\\ListMapper; use Sonata\\AdminBundle\\Datagrid\\DatagridMapper; use Sonata\\AdminBundle\\Form\\FormMapper;  class NewsAdmin extends EntityAdminBase {     protected function configureFormFields(FormMapper $formMapper)     {         parent::configureFormFields($formMapper);         $formMapper             -&gt;add('publishedAt', 'datetime')     }          protected function configureListFields(ListMapper $listMapper)     {         parent::configureListFields($listMapper);         $listMapper             -&gt;add('publishedAt')                         ;     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e, \u043e\u0431\u0449\u0438\u0435 \u0434\u043b\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u043f\u043e\u043b\u044f \u0432\u044b\u043d\u0435\u0441\u0435\u043d\u044b \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u043a\u043b\u0430\u0441\u0441, \u0430 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u044b\u0435 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u043a\u0430\u0436\u0434\u043e\u0439 \u0430\u0434\u043c\u0438\u043d\u043a\u0435. \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0434\u043b\u044f \u0430\u0434\u043c\u0438\u043d\u043e\u043a:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0430\u0434\u043c\u0438\u043d\u043a\u0438<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code># \/src\/App\/AppBundle\/Resources\/config\/admin.yml services:     sonata.admin.article:         class: App\\AppBundle\\Admin\\ArticleAdmin         tags:             - { name: sonata.admin, manager_type: orm, group: &quot;Content&quot;, label: &quot;Articles&quot; }         arguments:             - ~             - App\\AppBundle\\Entity\\Article             - ~         calls:             - [ setTranslationDomain, [admin]]          sonata.admin.news:         class: App\\AppBundle\\Admin\\NewsAdmin         tags:             - { name: sonata.admin, manager_type: orm, group: &quot;Content&quot;, label: &quot;News&quot; }         arguments:             - ~             - App\\AppBundle\\Entity\\News             - ~         calls:             - [ setTranslationDomain, [admin]]              # \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0430\u0434\u043c\u0438\u043d\u043a\u0438 \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0435 # \/app\/config\/config.yml imports:     - { resource: parameters.yml }     - { resource: security.yml }     - { resource: @AppBundle\/Resources\/config\/admin.yml } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0451, \u0441\u043e\u043d\u0430\u0442\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0432\u0441\u0451 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0434\u043b\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u043f\u0438\u0441\u043a\u043e\u0432 \u0441\u0442\u0430\u0442\u0435\u0439 \u0438 \u043d\u043e\u0432\u043e\u0441\u0442\u0435\u0439.<\/p>\n<h4>\u0425\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u0432\u044f\u0437\u0435\u0439 \u0442\u0435\u0433\u043e\u0432 \u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0432 \u043e\u0434\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435<\/h4>\n<p>  \u0418 \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u044f \u043d\u0435 \u043e\u0431\u0440\u0430\u0442\u0438\u043b \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0434\u043b\u044f \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0432\u044f\u0437\u0438 \u041c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u041c\u043d\u043e\u0433\u0438\u043c \u0441 \u0442\u0435\u0433\u0430\u043c\u0438. (\u0415\u0441\u043b\u0438 \u0431\u044b \u0443 \u043c\u0435\u043d\u044f \u0431\u044b\u043b\u043e \u0432\u0441\u0435\u0433\u043e \u043f\u0430\u0440\u0443 \u0442\u0430\u043a\u0438\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u044f \u0431\u044b, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0438 \u043d\u0435 \u043f\u0430\u0440\u0438\u043b\u0441\u044f \u0441 \u044d\u0442\u0438\u043c, \u043d\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u043d\u0435 \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0435\u043c\u044c \u0440\u0430\u0437\u043d\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0446, \u0430 \u043f\u043e\u0442\u043e\u043c \u0435\u0449\u0451 \u0438 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0438\u0441\u043a \u043f\u043e \u044d\u0442\u0438\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c.) \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430\u0448\u0451\u043b \u0431\u0430\u043d\u0434\u043b <a href=\"http:\/\/knpbundles.com\/FabienPennequin\/FPNTagBundle\">FPNTagBundle<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u0442 \u0441\u0432\u044f\u0437\u044c \u041c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u041c\u043d\u043e\u0433\u0438\u043c \u043d\u0430 \u0434\u0432\u0435 \u0441\u0432\u044f\u0437\u0438 \u041c\u043d\u043e\u0433\u0438\u0435-\u043a-\u041e\u0434\u043d\u043e\u043c\u0443 \u0438 \u041e\u0434\u0438\u043d-\u043a\u043e-\u041c\u043d\u043e\u0433\u0438\u043c \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 Tagging. \u0412 \u043e\u0431\u0449\u0435\u043c-\u0442\u043e, \u0442\u0430\u043a\u043e\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0432 DoctrineExtentions, \u0430 \u0431\u0430\u043d\u0434\u043b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0445 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044e \u0432 Symfony \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 TagManager. \u041e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u0431\u0430\u043d\u0434\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0435\u043b\u0430\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u0443\u044e \u0432\u0435\u0449\u044c \u2014 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0434\u043d\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043f\u043e\u043b\u0435\u043c ResourceType \u2014 \u0442\u0438\u043f\u043e\u043c \u0437\u0430\u043f\u0438\u0441\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u0433. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e Sonata \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435 \u0441\u0432\u044f\u0437\u0438, \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u0434\u043c\u0438\u043d\u043a\u0443 \u0442\u0430\u043a \u0436\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f.<\/p>\n<p>  \u041d\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u043d\u0435\u0441\u0435\u043d\u044b \u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0411\u0430\u0437\u043e\u0432\u0430\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c Entity<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">namespace App\\AppBundle\\Entity;  use Doctrine\\ORM\\Mapping as ORM; use Doctrine\\Common\\Collections\\ArrayCollection;  class Entity {     \/\/ \u0441\u0442\u0430\u0440\u044b\u0435 \u043f\u043e\u043b\u044f     \/\/ \u0441\u0442\u0430\u0440\u044b\u0435 \u0433\u0435\u0442\u0442\u0435\u0440\u044b \u0438 \u0441\u0435\u0442\u0442\u0435\u0440\u044b          \/\/ \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 - \u0431\u0435\u0437 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0439 \u0434\u043e\u043a\u0442\u0440\u0438\u043d\u044b!     protected $tags;          public function getTags()     {         return $this-&gt;tags ?: $this-&gt;tags = new ArrayCollection();     }      public function getTaggableType()     {         \/\/ \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0438\u043f\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043a\u043b\u0430\u0441\u0441 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 (\u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0432 \u043d\u0435\u0439\u043c\u0441\u043f\u0435\u0439\u0441)         return substr(strrchr(get_class($this), &quot;\\\\&quot;), 1);     }      public function getTaggableId()     {         return $this-&gt;getId();     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u0443\u0449\u043d\u043e\u0441\u0442\u044c Article<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">namespace App\\AppBundle\\Entity;  use Doctrine\\ORM\\Mapping as ORM;  \/**  * @ORM\\Table()  * @ORM\\Entity()  *\/ class Article extends Entity {  } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u0443\u0449\u043d\u043e\u0441\u0442\u044c News<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">namespace App\\AppBundle\\Entity;  use Doctrine\\ORM\\Mapping as ORM;  \/**  * @ORM\\Table()  * @ORM\\Entity()  *\/ class News extends Entity {     \/**      * @var \\DateTime      * @ORM\\Column(type=&quot;datetime&quot;, nullable=true)      *\/     protected $publishedAt;           \/**      * Set publishedAt      * @param \\DateTime $publishedAt      * @return News      *\/     public function setPublishedAt($publishedAt)     {         $this-&gt;publishedAt = $publishedAt;         return $this;     }      \/**      * Get publishedAt      * @return \\DateTime      *\/     public function getPublishedAt()     {         return $this-&gt;publishedAt;     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0418\u0437\u043c\u0435\u043d\u0451\u043d\u043d\u0430\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c Tag<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">namespace App\\AppBundle\\Entity;  use \\Doctrine\\ORM\\Mapping as ORM; use \\FPN\\TagBundle\\Entity\\Tag as BaseTag;  \/**  * @ORM\\Table()  * @ORM\\Entity()  *\/ class Tag extends BaseTag {     \/**      * @ORM\\Column(name=&quot;id&quot;, type=&quot;integer&quot;)      * @ORM\\Id      * @ORM\\GeneratedValue(strategy=&quot;AUTO&quot;)      *\/     protected $id;          \/**      * @ORM\\OneToMany(targetEntity=&quot;Tagging&quot;, mappedBy=&quot;tag&quot;, fetch=&quot;EAGER&quot;)      **\/     protected $tagging;          \/**      * @return integer       *\/     public function getId()     {         return $this-&gt;id;     } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u0443\u0449\u043d\u043e\u0441\u0442\u044c Tagging<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">namespace App\\AppBundle\\Entity;  use Doctrine\\ORM\\Mapping as ORM; use Doctrine\\ORM\\Mapping\\UniqueConstraint; use \\FPN\\TagBundle\\Entity\\Tagging as BaseTagging;  \/**  * @ORM\\Table(uniqueConstraints={@UniqueConstraint(name=&quot;tagging_idx&quot;, columns={&quot;tag_id&quot;, &quot;resource_type&quot;, &quot;resource_id&quot;})})  * @ORM\\Entity  *\/ class Tagging extends BaseTagging {     \/**      * @ORM\\Column(name=&quot;id&quot;, type=&quot;integer&quot;)      * @ORM\\Id      * @ORM\\GeneratedValue(strategy=&quot;AUTO&quot;)      *\/     protected $id;      \/**      * @ORM\\ManyToOne(targetEntity=&quot;Tag&quot;, inversedBy=&quot;tagging&quot;)      * @ORM\\JoinColumn(name=&quot;tag_id&quot;, referencedColumnName=&quot;id&quot;)      **\/     protected $tag;    } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0422\u0435\u0433\u0438 \u0432\u044b\u043d\u0435\u0441\u0435\u043d\u044b \u0432 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c, \u043a\u043b\u0430\u0441\u0441\u044b \u0441\u0430\u043c\u0438\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043b\u0438\u0448\u043d\u0435\u0433\u043e.<\/p>\n<p>  \u041d\u0430\u0447\u0430\u043b \u043a\u043e\u043f\u0430\u0442\u044c \u043a\u043e\u0434 SonataAdminBundle \u0432 \u043f\u043e\u0438\u0441\u043a\u0430\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043a\u0430\u043a \u043d\u0430\u0443\u0447\u0438\u0442\u044c \u0435\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0442\u0430\u043a\u0438\u043c\u0438 \u0442\u0435\u0433\u0430\u043c\u0438, \u043d\u0430\u0431\u0440\u0451\u043b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430 <a href=\"http:\/\/sonata-project.org\/bundles\/admin\/2-2\/doc\/reference\/saving_hooks.html\">\u0445\u0443\u043a\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f (Saving hooks)<\/a>, \u043e\u0442\u043c\u0451\u043b \u0438\u0445 \u0438 \u0441\u0442\u0430\u043b \u0438\u0441\u043a\u0430\u0442\u044c, \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u043f\u043e\u043b\u044f, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0432\u043d\u0435\u0434\u0440\u0438\u0442\u044c \u0437\u0430\u043f\u0443\u0441\u043a TagManager-\u0430. \u041d\u043e \u043d\u0435 \u043e\u0441\u0438\u043b\u0438\u043b, \u0442\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0437\u0430\u043f\u0443\u0442\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434. \u0418 \u0442\u0443\u0442 \u044f \u043e\u0431\u0440\u0430\u0442\u0438\u043b \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u0442\u0435\u0433\u043e\u0432 \u0432 \u0430\u0434\u043c\u043d\u043a\u0435 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0432\u043e\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0438\u0441\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u0435\u0433\u043e\u0432 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f, \u0438 \u043f\u0440\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438 \u0442\u0435\u0433\u0438 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e $tags \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438. \u041f\u0440\u0430\u0432\u0434\u0430, \u0441\u043e\u043d\u0430\u0442\u0430 \u043d\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0438\u0445 \u0432 \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0443 \u044d\u0442\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0435\u0442 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0439 \u0434\u043e\u043a\u0442\u0440\u0438\u043d\u044b, \u0434\u0430 \u0438 \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0438 \u0431\u044b\u043b\u0438 \u0431\u044b), \u043d\u043e \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0442\u0435\u0433\u043e\u0432 \u0432 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0442\u0435\u0433\u043e\u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u2014 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b TagManager! \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0442\u0435\u0433\u043e\u0432 \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438, \u0438 \u0442\u0443\u0442 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u043b\u0438\u0441\u044c \u0438\u043c\u0435\u043d\u043d\u043e Saving hooks.<\/p>\n<p>  \u0412 \u043a\u043b\u0430\u0441\u0441\u0435 \u0430\u0434\u043c\u0438\u043d\u043a\u0438 \u044f \u043d\u0435 \u0441\u0442\u0430\u043b \u043c\u0435\u043d\u044f\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u044f \u0442\u0435\u0433\u043e\u0432, \u0438 \u0441\u043e\u043d\u0430\u0442\u0430 \u0437\u0430\u043d\u043e\u0441\u0438\u0442 \u0442\u0435\u0433\u0438 \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e-\u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044e \u043f\u0440\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0438. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0445\u0443\u043a\u043e\u0432 postPersist \u0438 postUpdate \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u0432\u044f\u0437\u0438 \u0442\u0435\u0433\u043e\u0432 \u0432 \u0431\u0430\u0437\u0443:  <\/p>\n<pre><code class=\"php\">    \/**      * @return FPN\\TagBundle\\Entity\\TagManager      *\/     protected function getTagManager() {         return $this-&gt;getConfigurationPool()-&gt;getContainer()             -&gt;get('fpn_tag.tag_manager');     }          public function postPersist($object) {         $this-&gt;getTagManager()-&gt;saveTagging($object);     }          public function postUpdate($object) {         $this-&gt;getTagManager()-&gt;saveTagging($object);     }      public function preRemove($object) {         $this-&gt;getTagManager()-&gt;deleteTagging($object);         $this-&gt;getDoctrine()-&gt;getManager()-&gt;flush();     } <\/code><\/pre>\n<p>  \u0422\u0443\u0442 \u0435\u0441\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u0437\u0430\u0441\u0430\u0434\u0430 \u2014 <a href=\"https:\/\/github.com\/sonata-project\/SonataAdminBundle\/pull\/1318\">\u0431\u0430\u0433 \u0432 \u0421\u043e\u043d\u0430\u0442\u0435<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0432 \u043f\u0430\u043a\u0435\u0442\u043d\u043e\u043c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 (\u0432 \u0441\u043f\u0438\u0441\u043a\u0435) \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0445\u0443\u043a\u0438 preRemove \u0438 postRemove. \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e CRUD-\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0441\u043e\u043d\u0430\u0442\u044b:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 CRUD-\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">namespace App\\AppBundle\\Controller;  use Sonata\\AdminBundle\\Controller\\CRUDController as Controller; use Symfony\\Component\\HttpFoundation\\RedirectResponse; use Sonata\\AdminBundle\\Datagrid\\ProxyQueryInterface;  class CRUDController extends Controller {      public function publishAction()     {         $id = $this-&gt;get('request')-&gt;get($this-&gt;admin-&gt;getIdParameter());         $object = $this-&gt;admin-&gt;getObject($id);                  if (!$object) {             throw new NotFoundHttpException(sprintf('unable to find the object with id : %s', $id));         }                  $object-&gt;togglePublished();         $this-&gt;admin-&gt;getModelManager()-&gt;update($object);                  $message = $object-&gt;getPublished() ? 'Publish successfully' : 'Unpublish successfully';         $this-&gt;addFlash('sonata_flash_success', $this-&gt;get('translator.default')-&gt;trans($message, array(), 'admin'));         return new RedirectResponse($this-&gt;admin-&gt;generateUrl('list'));     }          public function batchActionDelete(ProxyQueryInterface $query)     {         if (method_exists($this-&gt;admin, 'preRemove')) {             foreach ($query-&gt;getQuery()-&gt;iterate() as $object) {                                 $this-&gt;admin-&gt;preRemove($object[0]);             }         }                  $response = parent::batchActionDelete($query);                  if (method_exists($this-&gt;admin, 'postRemove')) {             foreach ($query-&gt;getQuery()-&gt;iterate() as $object) {                                 $this-&gt;admin-&gt;postRemove($object[0]);             }         }                  return $response;     }  } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0412 \u044d\u0442\u043e\u0442 \u0436\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043a\u043d\u043e\u043f\u043a\u0438 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439. \u0414\u043b\u044f \u044d\u0442\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0438 \u043d\u0443\u0436\u0435\u043d \u0435\u0449\u0451 twig-\u0448\u0430\u0431\u043b\u043e\u043d \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 configureListFields \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 \u0430\u0434\u043c\u0438\u043d\u043a\u0438:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0428\u0430\u0431\u043b\u043e\u043d \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0432 \u0441\u043f\u0438\u0441\u043a\u0435<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code>{# src\/App\/AppBundle\/Resources\/views\/CRUD\/list__action_publish.html.twig #}  {% if object.published %}     &lt;a class=&quot;btn btn-sm btn-danger&quot; href=&quot;{{ admin.generateObjectUrl('publish', object) }}&quot;&gt;{% trans from 'admin' %}Unpublish{% endtrans %}&lt;\/a&gt; {% else %}     &lt;a class=&quot;btn btn-sm btn-success&quot; href=&quot;{{ admin.generateObjectUrl('publish', object) }}&quot;&gt;{% trans from 'admin' %}Publish{% endtrans %}&lt;\/a&gt; {% endif %} <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0432 \u0441\u043f\u0438\u0441\u043a\u0435<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">protected function configureListFields(ListMapper $listMapper) {     $listMapper         \/\/ \u043f\u0440\u043e\u0447\u0438\u0435 \u043f\u043e\u043b\u044f             -&gt;add('_action', 'actions', array(             'actions' =&gt; array(                 'Publish' =&gt; array(                     'template' =&gt; 'AppBundle:CRUD:list__action_publish.html.twig'                 )             )         ))     ; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0414\u043b\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0435\u0433\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 (AppBundle:CRUD) \u0442\u0440\u0435\u0442\u044c\u0438\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430.<\/p>\n<p>  \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u0432\u044b\u0432\u043e\u0434 \u0443\u0436\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u0445 \u0442\u0435\u0433\u043e\u0432 \u043f\u0440\u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438. \u0420\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u2014 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0442\u0435\u0433\u043e\u0432 \u0432 \u043f\u043e\u043b\u0435 tags \u0442\u0438\u043f\u0430 entity:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0412\u044b\u0432\u043e\u0434 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u0445 \u0442\u0435\u0433\u043e\u0432<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">protected function configureFormFields(FormMapper $formMapper) {     $tags = $this-&gt;hasSubject()         ? $this-&gt;getTagManager()-&gt;loadTagging($this-&gt;getSubject())         : array();          $formMapper         \/\/ \u043f\u0440\u043e\u0447\u0438\u0435 \u043f\u043e\u043b\u044f         -&gt;add('tags', 'entity', array('class'=&gt;'AppBundle:Tag', 'choices' =&gt; $tags, 'multiple' =&gt; true, 'attr'=&gt;array('style'=&gt;'width: 100%;')))     ; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<h4>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h4>\n<p>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0432\u043d\u0435\u0434\u0440\u0438\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0431\u0430\u043d\u0434\u043b FPNTagBundle \u0432 \u0430\u0434\u043c\u0438\u043d\u043a\u0443 SonataAdminBundle, \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0441\u0432\u044f\u0437\u0435\u0439 \u0432 \u043e\u0434\u043d\u0443 \u043e\u0431\u0449\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0448\u0435 \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0421\u043e\u043d\u0430\u0442\u044b.<\/p>\n<h4>\u0411\u043e\u043d\u0443\u0441 \u2014 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u0435\u0433\u0430\u043c\u0438<\/h4>\n<p>  \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0437\u0430\u0434 \u044f <a href=\"http:\/\/habrahabr.ru\/post\/229427\/#comment_7781487\">\u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 \u043e\u0431\u0435\u0449\u0430\u043b<\/a> \u0432\u044b\u043b\u043e\u0436\u0438\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e \u0441 \u043d\u0430\u0431\u043e\u0440\u043e\u043c SQL-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0442\u0435\u0433\u0430\u043c\u0438. \u041e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e \u044f \u043d\u0435 \u0441\u0442\u0430\u043b \u0434\u0435\u043b\u0430\u0442\u044c, \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u0438\u0445 \u0437\u0434\u0435\u0441\u044c.<\/p>\n<p>  \u0414\u0430\u043d\u043e:   <\/p>\n<ul>\n<li>\u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d\u043d\u044b\u0435 \u0432\u044b\u0448\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b Article, News, Tag, Tagging<\/li>\n<li>\u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u0433\u043e\u0432 (\u0441\u043f\u0438\u0441\u043e\u043a id), \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0440\u0435\u043b\u0435\u0432\u0430\u043d\u0442\u043d\u044b\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438. \u0411\u0443\u0434\u0435\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u0442\u0435\u0433\u043e\u0432 \u0443 \u043d\u0430\u0441 3, \u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0438 \u0431\u043e\u043b\u044c\u0448\u0435.<\/li>\n<\/ul>\n<p>  \u0417\u0430\u0434\u0430\u0447\u0430: \u041d\u0430\u0439\u0442\u0438 \u0432\u0441\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u0438 \u043d\u043e\u0432\u043e\u0441\u0442\u0438, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0442\u0435\u0433\u0438, \u043f\u0440\u0438\u0447\u0451\u043c \u0432\u043d\u0430\u0447\u0430\u043b\u0435 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0437\u0430\u043f\u0438\u0441\u0438, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u0432\u0441\u0435 \u0442\u0440\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u0442\u0435\u0433\u0430, \u0434\u0430\u043b\u0435\u0435 \u2014 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0437\u0430\u043f\u0438\u0441\u0438, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u0445\u043e\u0442\u044f \u0431\u044b \u0434\u0432\u0430 \u043b\u044e\u0431\u044b\u0445 \u0432\u0432\u0435\u0434\u0451\u043d\u043d\u044b\u0445 \u0442\u0435\u0433\u0430, \u0438 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0437\u0430\u043f\u0438\u0441\u0438, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u0438\u043d \u0442\u0435\u0433.<\/p>\n<p>  \u041f\u0435\u0440\u0432\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 id \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 (\u0438 \u0442\u0438\u043f \u0437\u0430\u043f\u0438\u0441\u0438)  <\/p>\n<pre><code class=\"sql\">SELECT resource_id, resource_type, count(*) as weight FROM Tagging  WHERE tag_id IN (1,2,3) GROUP BY resource_id ORDER BY weight DESC <\/code><\/pre>\n<p>  \u0412\u0442\u043e\u0440\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0445 \u0441\u0442\u0430\u0442\u0435\u0439:  <\/p>\n<pre><code class=\"sql\">SELECT Article.id, Article.title FROM Tagging, Article  WHERE Tagging.resource_id=Article.id AND Tagging.tag_id IN (1,2,3)  GROUP BY Tagging.resource_id ORDER BY count(*) DESC <\/code><\/pre>\n<p>  \u0425\u0430\u0431\u0440\u0430\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c <a href=\"http:\/\/habrahabr.ru\/users\/nashev\/\" class=\"user_link\">Nashev<\/a> \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u043b \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0441 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0442\u0435\u0433\u043e\u0432, \u0442\u043e \u0435\u0441\u0442\u044c, \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0432\u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0438, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u0442\u0435\u0433\u0438 (1, 2, 3) \u0438 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 (4, 5, 6):  <\/p>\n<pre><code class=\"sql\">SELECT resource_id, resource_type FROM Tagging WHERE tag_id IN (1,2,3)  AND resource_id NOT IN (SELECT resource_id FROM Tagging WHERE tag_id IN (4,5,6)) GROUP BY resource_id ORDER BY count(*) DESC <\/code><\/pre>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/233695\/\"> http:\/\/habrahabr.ru\/post\/233695\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">     \t\u041c\u043d\u043e\u0433\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0431\u0430\u043d\u0434\u043b\u043e\u043c <a href=\"https:\/\/github.com\/sonata-project\/SonataAdminBundle\">SonataAdminBundle<\/a> \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0430 Symfony2. \u042d\u0442\u043e\u0442 \u0431\u0430\u043d\u0434\u043b \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432 \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0435 \u0441\u0440\u043e\u043a\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c CRUD-\u0430\u0434\u043c\u0438\u043d\u043a\u0443 \u0434\u043b\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 Doctrine \u0438 Mongo. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u043b\u0435\u0433\u043a\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0438 \u0434\u043b\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0438\u043c\u0438 \u0441\u0432\u044f\u0437\u0438 \u041e\u0434\u0438\u043d-\u043a\u043e-\u041c\u043d\u043e\u0433\u0438\u043c \u0438 \u041c\u043d\u043e\u0433\u0438\u0435-\u043a\u043e-\u041c\u043d\u043e\u0433\u0438\u043c. \u0412\u043e\u0442 \u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u043f\u0443\u043d\u043a\u0442\u043e\u043c \u0443 \u043c\u0435\u043d\u044f \u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0442\u0435\u0433\u043e\u0432 \u0434\u043b\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044f \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u043d\u0443 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0430\u043d\u0434\u043b\u0430 <a href=\"http:\/\/knpbundles.com\/FabienPennequin\/FPNTagBundle\">FPNTagBundle<\/a>, \u0438 \u0447\u0442\u043e \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e\u0442 \u0431\u0430\u043d\u0434\u043b \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0432 SonataAdmin.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-233695","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/233695","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=233695"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/233695\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=233695"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=233695"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=233695"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}