跟我一塊兒用Symfony寫一個博客網站;

個人微信公衆號感興趣的話能夠掃一下,php

或者加微信號   whenDreamscss

第一部分:基礎設置,跑起一個頁面-首頁html

第一步:html5

composer create-project symfony/framework-standard-edition 你的項目名;jquery


建立完這個原型,我執行php bin/console server:run,能夠跑起來;web

那麼此刻你須要鏈接數據庫了:個人數據庫是PostgreSqlajax

寫一個數據庫建立腳本例如個人sql

create user myblog with password 'myblog' ;
ALTER USER myblog WITH PASSWORD 'myblog';

create database myblog_dev with encoding='utf8' ;
create database myblog_prod with encoding='utf8' ;
create database myblog_test with encoding='utf8' ;

grant all privileges on database myblog_dev to myblog ;
grant all privileges on database myblog_test to myblog;
grant all privileges on database myblog_prod to myblog;

\connect myblog_dev;
create schema extensions;
create extension hstore schema extensions;
ALTER DATABASE myblog_dev SET search_path to "$user",public,extensions;
alter database myblog_dev owner to myblog;
alter schema public owner to myblog;
alter schema extensions owner to myblog;
GRANT USAGE ON SCHEMA public to myblog;

\connect myblog_prod;
create schema extensions;
create extension hstore schema extensions;
ALTER DATABASE myblog_dev SET search_path to "$user",public,extensions;
alter database myblog_dev owner to myblog;
alter schema public owner to myblog;
alter schema extensions owner to myblog;
GRANT USAGE ON SCHEMA public to myblog;


\connect myblog_test;
create schema extensions;
create extension hstore schema extensions;
ALTER DATABASE myblog_dev SET search_path to "$user",public,extensions;
alter database myblog_dev owner to myblog;
alter schema public owner to myblog;
alter schema extensions owner to myblog;
GRANT USAGE ON SCHEMA public to myblog;
View Code

根據腳本建立數據庫。mongodb

第二步,讓你的程序這個原型程序鏈接數據庫:數據庫

找到config.yml

複製代碼:

# Doctrine Configuration
doctrine:
    dbal:
        driver:   %database_driver%
        host:     %database_host%
        port:     %database_port%
        dbname:   %database_name%
        user:     %database_user%
        password: %database_password%
        charset:  UTF8
View Code

找到parameters.yml和parameters.yml.dist

鏈接你的數據庫名字(配置同樣的):

# This file is auto-generated during the composer install
parameters:
    database_driver: pdo_pgsql
    database_host: 127.0.0.1
    database_port: null
    database_name: 數據庫名字
    database_user: 數據庫用戶名
    database_password: 數據庫密碼
    mailer_transport: smtp
    mailer_host: 127.0.0.1
    mailer_user: 
    mailer_password: 
    secret: ThisTokenIsNotSoSecretChangeIt
View Code

這樣就連上數據庫了;

-----------------------------------------------

第三步,根據業務需求開始寫Bundle:

注:bundle的真義在於,它是做爲軟件的一個「可被複用」的獨立構成而存在。若是UserBundle不能「原封不動地」使用在別的Symfony程序中,它不該該成爲bundle。另外,若是InvoiceBundle依賴於ProductBundle,那便沒有任何須要將它們分紅兩個bundle。

如下是建立Bundle的命令:在這裏我不打算建立新Bundle

php bin/console generate:bundle --namespace=AppBundle --dir=src --format=annotation --no-interaction

 

第三步,找到首頁更改首頁,寫一個服務測試一下;

首頁在個人AppBundle下面的Resources/views/Default/index.html.twig

若是沒有自行新建這個目錄;

寫一個註冊一個服務

先在src/AppBundle/Utils/建立一個新的Slugger類並添加下面的slugify()方法

// src/AppBundle/Utils/Slugger.php
namespace AppBundle\Utils;
 
class Slugger
{
    public function slugify($string)
    {
        return preg_replace(
            '/[^a-z0-9]/', '-', strtolower(trim(strip_tags($string)))
        );
    }
}
View Code

而後,爲這個類定義一個服務:

# app/config/services.yml
services:
    # keep your service names short
    app.slugger:
        class: AppBundle\Utils\Slugger
View Code

那麼我開始修改個人首頁:

    /**
     * @Route("/", name="homepage")
     */
    public function indexAction(Request $request)
    {
   
        //獲得服務
        $slug = $this->get('app.slugger')->slugify("DREAM START");

        return $this->render('AppBundle:Default:index.html.twig',
            array('slug' => $slug));
    }
View Code

那麼我在頁面上取slug,只須要加上{{slug}}這樣就能夠了。

好了首頁部分結束;

注:剛纔的服務註冊寫在了config目錄下的service.yml裏,

我須要更改一下,應該寫在AppBundle/Resources/config/service.yml 下,這樣更好一些

而後在在config.yml文件中import就能夠了以下添加:

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    - { resource: services.yml }
    - { resource: "@AppBundle/Resources/config/services.yml" }
View Code

 

第二部分:根據業務需求開始寫實體;

首先我安裝了DoctrineMigrationsBundle,用於數據庫migration;

(數據庫遷移功能是數據庫抽象層的擴展,可以讓您以安全,簡單和標準化的方式以編程方式部署新版本的數據庫模式)

官方地址:http://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html

$ composer require doctrine/doctrine-migrations-bundle "^1.0"
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 5 installs, 0 updates, 0 removals
  - Installing zendframework/zend-eventmanager (3.0.1) Downloading: 100%
  - Installing zendframework/zend-code (2.6.3) Downloading: 100%
  - Installing ocramius/proxy-manager (1.0.2) Downloading: 100%
  - Installing doctrine/migrations (v1.5.0) Downloading: 100%
  - Installing doctrine/doctrine-migrations-bundle (v1.2.1) Downloading: 100%
zendframework/zend-eventmanager suggests installing container-interop/container-interop (^1.1.0, to use the lazy listeners feature)
zendframework/zend-eventmanager suggests installing zendframework/zend-stdlib (^2.7.3 || ^3.0, to use the FilterChain feature)
zendframework/zend-code suggests installing zendframework/zend-stdlib (Zend\Stdlib component)
ocramius/proxy-manager suggests installing zendframework/zend-stdlib (To use the hydrator proxy)
ocramius/proxy-manager suggests installing ocramius/generated-hydrator (To have very fast object to array to object conversion for ghost objects)
ocramius/proxy-manager suggests installing zendframework/zend-xmlrpc (To have the XmlRpc adapter (Remote Object feature))
ocramius/proxy-manager suggests installing zendframework/zend-json (To have the JsonRpc adapter (Remote Object feature))
ocramius/proxy-manager suggests installing zendframework/zend-soap (To have the Soap adapter (Remote Object feature))
Writing lock file
Generating autoload files
> Incenteev\ParameterHandler\ScriptHandler::buildParameters
Updating the "app/config/parameters.yml" file
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::buildBootstrap
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache

 // Clearing the cache for the dev environment with debug true

 [OK] Cache for the "dev" environment (debug=true) was successfully cleared.

> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::installAssets

 Trying to install assets as relative symbolic links.

 -- -------- ----------------
     Bundle   Method / Error
 -- -------- ----------------

 [OK] All assets were successfully installed.

> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::installRequirementsFile
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::prepareDeploymentTarget
View Code

引入新bundle,

1:composer 加載,

$ composer require doctrine/doctrine-migrations-bundle "^1.0"

2:在Appkernel.php中註冊new,

  new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(),

3:配置config.yml,添加

doctrine_migrations:
    dir_name: "%kernel.root_dir%/DoctrineMigrations"
    namespace: Application\Migrations
    table_name: migration_versions
    name: Application Migrations

 

運行如下命令查看一下:

$ php bin/console doctrine:migrations:status

 == Configuration

    >> Name:                                               Application Migrations
    >> Database Driver:                                    pdo_pgsql
    >> Database Name:                                      dreamstart_dev
    >> Configuration Source:                               manually configured
    >> Version Table Name:                                 migration_versions
    >> Version Column Name:                                version
    >> Migrations Namespace:                               Application\Migrations
    >> Migrations Directory:                               C:\home\workspace\dreamstart\app/DoctrineMigrations
    >> Previous Version:                                   Already at first version
    >> Current Version:                                    0
    >> Next Version:                                       Already at latest version
    >> Latest Version:                                     0
    >> Executed Migrations:                                0
    >> Executed Unavailable Migrations:                    0
    >> Available Migrations:                               0
    >> New Migrations:                                     0
View Code

而後我引入fosuserbundle,用於安全認證;

https://symfony.com/doc/current/bundles/FOSUserBundle/index.html#main

須要7步安裝:

  1. Download FOSUserBundle using composer //下載
  2. Enable the Bundle                                //啓用
  3. Create your User class                             //建立User類
  4. Configure your application's security.yml   //配置security
  5. Configure the FOSUserBundle                   //配置FOSUserBundle
  6. Import FOSUserBundle routing                 //導入routing
  7. Update your database schema                  //更新數據庫
下載:
$ composer require friendsofsymfony/user-bundle "~1.3"

 啓用:

<?php
// app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        // ...
        new FOS\UserBundle\FOSUserBundle(),
        // ...
    );
}
View Code

 建立User類:

<?php

namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="dream_user")
 */
class User extends BaseUser
{

    //構造函數
    public function __construct()
    {
        parent::__construct();
        // your own logic
    }
    
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;



}
View Code

 配置security

# app/config/security.yml
security:
    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt

    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_SUPER_ADMIN: ROLE_ADMIN

    providers:
        fos_userbundle:
            id: fos_user.user_provider.username

    firewalls:
        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                csrf_provider: security.csrf.token_manager # Use form.csrf_provider instead for Symfony <2.4
            logout:       true
            anonymous:    true

    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/, role: ROLE_ADMIN }
View Code

配置FOSUserBundle

# app/config/config.yml
fos_user:
    db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
    firewall_name: main
    user_class: AppBundle\Entity\User

導入routing

# app/config/routing.yml
fos_user_security: resource: "@FOSUserBundle/Resources/config/routing/all.xml"

更新數據庫
$ php app/console doctrine:schema:update --force

  將security.yml

csrf_provider: security.csrf.token_manager
改成:csrf_token_generator: security.csrf.token_manager

如今咱們用戶bundle能夠正常使用了;
-----------------------------------
接下來我打算仍是新建一個Bundle,做爲前臺Bundle;
php bin/console generate:bundle;
此命令執行後會一連串的與終端互動以下,默認便可
peng@PENG-PC /C/home/workspace/dreamstart (master)
$ php bin/console generate:bundle


  Welcome to the Symfony bundle generator!


Are you planning on sharing this bundle across multiple applications? [no]:

Your application code must be written in bundles. This command helps
you generate them easily.

Give your bundle a descriptive name, like BlogBundle.
Bundle name: WebBundle

Bundles are usually generated into the src/ directory. Unless you're
doing something custom, hit enter to keep this default!

Target Directory [src/]:

What format do you want to use for your generated configuration?

Configuration format (annotation, yml, xml, php) [annotation]:


  Bundle generation


> Generating a sample bundle skeleton into C:\home\workspace\dreamstart\app/../src/WebBundle
  created .\app/../src/WebBundle/
  created .\app/../src/WebBundle/WebBundle.php
  created .\app/../src/WebBundle/Controller/
  created .\app/../src/WebBundle/Controller/DefaultController.php
  created .\app/../tests/WebBundle/Controller/
  created .\app/../tests/WebBundle/Controller/DefaultControllerTest.php
  created .\app/../src/WebBundle/Resources/views/Default/
  created .\app/../src/WebBundle/Resources/views/Default/index.html.twig
  created .\app/../src/WebBundle/Resources/config/
  created .\app/../src/WebBundle/Resources/config/services.yml
> Checking that the bundle is autoloaded
> Enabling the bundle inside C:\home\workspace\dreamstart\app\AppKernel.php
  updated .\app\AppKernel.php
> Importing the bundle's routes from the C:\home\workspace\dreamstart\app\config\routing.yml file
  updated .\app/config/routing.yml
> Importing the bundle's services.yml from the C:\home\workspace\dreamstart\app\config\config.yml file
  updated .\app/config/config.yml


  Everything is OK! Now get to work :).
View Code

須要修改一下默認訪問頁面,如今只須要改一下routing文件

app:
    resource: '@AppBundle/Controller/'
    type: annotation
    prefix:   /admin

web:
    resource: "@WebBundle/Controller/"
    type:     annotation
    prefix:   /
View Code

如今默認頁面是WebBundle裏面的頁面了;

 

接下來就開始建立實體了:

業務分析一下,我大概須要寫兩個實體,一個是文章,一個是類別,其他的暫時不須要;

實體建立過程:

 

$ php bin/console doctrine:generate:entity


  Welcome to the Doctrine2 entity generator



This command helps you generate Doctrine2 entities.

First, you need to give the entity name you want to generate.
You must use the shortcut notation like AcmeBlogBundle:Post.

The Entity shortcut name: AppBundle:Category

Determine the format to use for the mapping information.

Configuration format (yml, xml, php, or annotation) [annotation]:

Instead of starting with a blank entity, you can add some fields now.
Note that the primary key will be added automatically (named id).

Available types: array, simple_array, json_array, object,
boolean, integer, smallint, bigint, string, text, datetime, datetimetz,
date, time, decimal, float, binary, blob, guid.

New field name (press <return> to stop adding fields): name
Field type [string]:
Field length [255]:
Is nullable [false]:
Unique [false]:

New field name (press <return> to stop adding fields):


  Entity generation


  created .\src\AppBundle/Entity/Category.php
> Generating entity class C:\home\workspace\dreamstart\src\AppBundle\Entity\Category.php: OK!
> Generating repository class C:\home\workspace\dreamstart\src\AppBundle\Repository\CategoryRepository.php: OK!


  Everything is OK! Now get to work :).
View Code

 

$ php bin/console doctrine:generate:entity


  Welcome to the Doctrine2 entity generator



This command helps you generate Doctrine2 entities.

First, you need to give the entity name you want to generate.
You must use the shortcut notation like AcmeBlogBundle:Post.

The Entity shortcut name: AppBundle:Post

Determine the format to use for the mapping information.

Configuration format (yml, xml, php, or annotation) [annotation]:

Instead of starting with a blank entity, you can add some fields now.
Note that the primary key will be added automatically (named id).

Available types: array, simple_array, json_array, object,
boolean, integer, smallint, bigint, string, text, datetime, datetimetz,
date, time, decimal, float, binary, blob, guid.

New field name (press <return> to stop adding fields): name
Field type [string]:
Field length [255]:
Is nullable [false]:
Unique [false]:

New field name (press <return> to stop adding fields): content
Field type [string]: text
Is nullable [false]:
Unique [false]:

New field name (press <return> to stop adding fields): created
Field type [string]: datetime
Is nullable [false]:
Unique [false]:

New field name (press <return> to stop adding fields): modified
Field type [string]: datetime
Is nullable [false]:
Unique [false]:

New field name (press <return> to stop adding fields):


  Entity generation


  created .\src\AppBundle/Entity/Post.php
> Generating entity class C:\home\workspace\dreamstart\src\AppBundle\Entity\Post.php: OK!
> Generating repository class C:\home\workspace\dreamstart\src\AppBundle\Repository\PostRepository.php: OK!


  Everything is OK! Now get to work :).
View Code

 

須要在Post實體中增長與category的多對一關係,我只建一端,在Post實體中加便可:

    /**
     * @var string
     * @ORM\ManyToOne(targetEntity="Category")
     * @ORM\JoinColumn(name="category_id",referencedColumnName="id")
     */
    private $category;

而後驗證關聯關係是否正確:


$ php bin/console doctrine:schema:validate [Mapping] OK - The mapping files are correct. [Database] FAIL - The database schema is not in sync with the current mapping file. 這裏提示,數據庫沒有映射成功
咱們執行更新數據庫表命令 $ php bin
/console doctrine:schema:update --force Updating database schema... Database schema updated successfully! "6" queries were executed
這時候你的數據庫就多了兩張表

咱們從新生成getter和seter方法:

$ php bin/console doctrine:generate:entities AppBundle:Post
Generating entity "AppBundle\Entity\Post"
  > backing up Post.php to Post.php~
  > generating AppBundle\Entity\Post

好了已經自動生成了。

那麼如今就開始寫CRUD;

文章的CRUD,類型的CRUD;用戶的CRUD;

以下過程:

$ php bin/console generate:doctrine:crud


  Welcome to the Doctrine2 CRUD generator



This command helps you generate CRUD controllers and templates.

First, give the name of the existing entity for which you want to generate a CRUD
(use the shortcut notation like AcmeBlogBundle:Post)

The Entity shortcut name: AppBundle:Category

By default, the generator creates two actions: list and show.
You can also ask it to generate "write" actions: new, update, and delete.

Do you want to generate the "write" actions [no]? yes

Determine the format to use for the generated CRUD.

Configuration format (yml, xml, php, or annotation) [annotation]:

Determine the routes prefix (all the routes will be "mounted" under this
prefix: /prefix/, /prefix/new, ...).

Routes prefix [/category]:


  Summary before generation


You are going to generate a CRUD controller for "AppBundle:Category"
using the "annotation" format.

Do you confirm generation [yes]?


  CRUD generation


  created .\src\AppBundle/Controller//CategoryController.php
  created .\app/Resources/views/category/
  created .\app/Resources/views/category/index.html.twig
  created .\app/Resources/views/category/show.html.twig
  created .\app/Resources/views/category/new.html.twig
  created .\app/Resources/views/category/edit.html.twig
  created .\src\AppBundle/Tests/Controller/
  created .\src\AppBundle/Tests/Controller//CategoryControllerTest.php
Generating the CRUD code: OK
  created .\src\AppBundle/Form/
  created .\src\AppBundle/Form/CategoryType.php
Generating the Form code: OK
Updating the routing: OK


  Everything is OK! Now get to work :).



$ php bin/console generate:doctrine:crud


  Welcome to the Doctrine2 CRUD generator



This command helps you generate CRUD controllers and templates.

First, give the name of the existing entity for which you want to generate a CRUD
(use the shortcut notation like AcmeBlogBundle:Post)

The Entity shortcut name: AppBundle:Post

By default, the generator creates two actions: list and show.
You can also ask it to generate "write" actions: new, update, and delete.

Do you want to generate the "write" actions [no]? yes

Determine the format to use for the generated CRUD.

Configuration format (yml, xml, php, or annotation) [annotation]:

Determine the routes prefix (all the routes will be "mounted" under this
prefix: /prefix/, /prefix/new, ...).

Routes prefix [/post]:


  Summary before generation


You are going to generate a CRUD controller for "AppBundle:Post"
using the "annotation" format.

Do you confirm generation [yes]?


  CRUD generation


  created .\src\AppBundle/Controller//PostController.php
  created .\app/Resources/views/post/
  created .\app/Resources/views/post/index.html.twig
  created .\app/Resources/views/post/show.html.twig
  created .\app/Resources/views/post/new.html.twig
  created .\app/Resources/views/post/edit.html.twig
  created .\src\AppBundle/Tests/Controller//PostControllerTest.php
Generating the CRUD code: OK
  created .\src\AppBundle/Form/PostType.php
Generating the Form code: OK
Updating the routing: OK


  Everything is OK! Now get to work :).
View Code

 如今已經生成了Resources/views目錄下生成了相應的增刪改查頁面;

如今須要把後臺佈局頁面搭建起來:

步驟:

1:佈局:新建一個在AppBundle/Resources/views/新建Layout目錄;

2:在Layout新建admin.layout.html.twig;

  

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{% block title %}{% endblock  %} | {{ slug }}</title>

    <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">
    <!--[if lt IE 9]>
    <script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
    {% block header  %}{% endblock %}
</head>
<body style="background-color:#EFEFEF">
<nav class="navbar navbar-default navbar-inverse" role="navigation">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="">博客控制檯</a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">用戶管理 <span class="caret"></span></a>
                    <ul class="dropdown-menu" role="menu">
                        <li><a href="">用戶管理</a></li>
                        <li><a href="">2</a></li>
                    </ul>
                </li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">博客 <span class="caret"></span></a>
                    <ul class="dropdown-menu" role="menu">
                        <li><a href="">1</a></li>
                        <li><a href="">2</a></li>
                        <li><a href="">3</a></li>
                        <li><a href="">4</a></li>
                    </ul>
                </li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">2<span class="caret"></span></a>
                    <ul class="dropdown-menu" role="menu">
                        <li><a href="">1</a></li>
                        <li><a href="">2</a></li>
                    </ul>
                </li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">2<span class="caret"></span></a>
                    <ul class="dropdown-menu" role="menu">
                        <li><a href="">2</a></li>
                    </ul>
                </li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown">{{app.user.username}} <span class="caret"></span></a>
                    <ul class="dropdown-menu" role="menu">
                        <li><a href="{{path('fos_user_change_password')}}">修改密碼</a></li>
                        <li class="divider"></li>
                        <li><a href="{{path('fos_user_security_logout')}}">退出登陸</a></li>
                    </ul>
                </li>
            </ul>
        </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
</nav>

<div class="xin-staff-body" style="min-height:500px">
    <div class="container">
        {% include "AppBundle:include:notice.html.twig" %}
        {% block main %}{% endblock %}
    </div>
</div>
<div class="xin-staff-footer">
    <hr />
    <div class="clearfix">
        <div class="pull-right">
            <a href="mailto:turinguntion@163.com">技術支持</a>,
        </div>
    </div>
</div>
<script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
{% block footer %}{% endblock %}
</body>
</html>
View Code

 

3:修改index.hmtl.twing以下:

{% extends "AppBundle:Layout:admin.layout.html.twig" %}

{% block title %}博客控制檯{% endblock %}

{% block main %}


{% endblock %}

 那麼如今爲止後臺佈局就寫好了,其餘頁面都繼承這個佈局就行了,接下來,就開始修改一下CRUD以及頁面;

  

須要移動一下category和post到相應的Bundle的Resources下面;

此時也要改一下controller以下:index

    public function indexAction(Request $request)
    {
        $em = $this->getDoctrine()->getManager();
        $categories = $em->getRepository('AppBundle:Category')->findAll();
        return $this->render('AppBundle:Category:index.html.twig', array(
            'categories' => $categories
        ));
    }
View Code

對應的html以下:index.html.twig

{% extends "AppBundle:layout:admin.layout.html.twig" %}

{% block title %}管理控制檯{% endblock %}

{% block main %}
    <ol class="breadcrumb clearfix">
        <li><a href="{{ path('category_index') }}">類別管理</a></li>
        <li class="pull-right">
            <a href="{{ path('category_new' ) }}">新建</a>
        </li>
    </ol>

    <table class="table">
        <thead>
            <tr>
                <th>ID</th>
                <th>名稱</th>
                <th>操做</th>
            </tr>
        </thead>
        <tbody>
        {% for category in categories %}
            <tr>
                <td><a href="{{ path('category_show', { 'id': category.id }) }}">{{ category.id }}</a></td>
                <td>{{ category.name }}</td>
                <td>
                    <ul>
                        <li>
                            <a href="{{ path('category_show', { 'id': category.id }) }}">show</a>
                        </li>
                        <li>
                            <a href="{{ path('category_edit', { 'id': category.id }) }}">edit</a>
                        </li>
                    </ul>
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
{% endblock %}
View Code

其他頁面也進行修改。

咱們開始添加分頁功能

https://packagist.org/packages/knplabs/knp-paginator-bundle

1:把分頁Bundle加上

 composer.phar require knplabs/knp-paginator-bundle

$ composer.phar require knplabs/knp-paginator-bundle
Using version ^2.5 for knplabs/knp-paginator-bundle
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
  - Installing knplabs/knp-components (1.3.4) Loading from cache
  - Installing knplabs/knp-paginator-bundle (2.5.4) Downloading: 100%
knplabs/knp-components suggests installing doctrine/mongodb-odm (to allow usage pagination with Doctrine ODM MongoDB)
knplabs/knp-components suggests installing doctrine/phpcr-odm (to allow usage pagination with Doctrine ODM PHPCR)
knplabs/knp-components suggests installing propel/propel1 (to allow usage pagination with Propel ORM)
knplabs/knp-components suggests installing ruflin/Elastica (to allow usage pagination with ElasticSearch Client)
knplabs/knp-components suggests installing solarium/solarium (to allow usage pagination with Solarium Client)
Writing lock file
Generating autoload files
> Incenteev\ParameterHandler\ScriptHandler::buildParameters
Updating the "app/config/parameters.yml" file
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::buildBootstrap
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache

 // Clearing the cache for the dev environment with debug true

 [OK] Cache for the "dev" environment (debug=true) was successfully cleared.

> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::installAssets

 Trying to install assets as relative symbolic links.

 -- -------- ----------------
     Bundle   Method / Error
 -- -------- ----------------

 [OK] All assets were successfully installed.

> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::installRequirementsFile
> Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::prepareDeploymentTarget
View Code

 2:在AppKernel.php 註冊Bundle:

new Knp\Bundle\PaginatorBundle\KnpPaginatorBundle()

 3:在config.yml中添加

knp_paginator:
    page_range: 5                      # default page range used in pagination control
    default_options:
        page_name: page                # page query parameter name
        sort_field_name: sort          # sort field query parameter name
        sort_direction_name: direction # sort direction query parameter name
        distinct: true                 # ensure distinct results, useful when ORM queries are using GROUP BY statements
    template:
        pagination: 'KnpPaginatorBundle:Pagination:sliding.html.twig'     # sliding pagination controls template
        sortable: 'KnpPaginatorBundle:Pagination:sortable_link.html.twig' # sort link template
View Code

4:從新寫indexAction列表:

    /**
     * Lists all Category entities.
     *
     * @Route("/", name="category_index")
     * @Method("GET")
     * @Template()
     */
    public function indexAction(Request $request)
    {
        $em = $this->getDoctrine()->getManager();
        $query = $em->getRepository('AppBundle:Category')
                    ->createQueryBuilder('c')
                    ->getQuery();
        $paginator  = $this->get('knp_paginator');
        $pagination = $paginator->paginate(
            $query, 
            $request->query->getInt('page', 1), 1
        );
        return array(
            'pagination' => $pagination,
        );

    }
View Code

5:index.html

{% extends "AppBundle:layout:admin.layout.html.twig" %}

{% block title %}管理控制檯{% endblock %}

{% block main %}
    <ol class="breadcrumb clearfix">
        <li><a href="{{ path('category_index') }}">類別管理</a></li>
        <li class="pull-right">
            <a href="{{ path('category_new' ) }}">新建</a>
        </li>
    </ol>

    <table class="table">
        <thead>
            <tr>
                <th>ID</th>
                <th>名稱</th>
                <th>操做</th>
            </tr>
        </thead>
        <tbody>
        {% for category in pagination %}
            <tr>
                <td><a href="{{ path('category_show', { 'id': category.id }) }}">{{ category.id }}</a></td>
                <td>{{ category.name }}</td>
                <td>
                    <ul>
                        <li>
                            <a href="{{ path('category_show', { 'id': category.id }) }}">show</a>
                        </li>
                        <li>
                            <a href="{{ path('category_edit', { 'id': category.id }) }}">edit</a>
                        </li>
                    </ul>
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
    {{ knp_pagination_render(pagination, "KnpPaginatorBundle:Pagination:twitter_bootstrap_v3_pagination.html.twig") }}

{% endblock %}
View Code

 這樣咱們就建立好了最基本的CRUD了;剩下的頁面能夠本身建立,若是有問題能夠加我公衆號直接發消息給我公衆號:whenDreams,或者加Symfony的羣聯繫我 羣號:182983780;

----------------------------------------------------------------------------------------

接下來我須要寫一個用戶的CRUD將全過程記錄,前提已經成功引入了FOSUserBundle

1:命令建立CRUD以下:

app/console doctrine:generate:crud


  Welcome to the Doctrine2 CRUD generator



This command helps you generate CRUD controllers and templates.

First, you need to give the entity for which you want to generate a CRUD.
You can give an entity that does not exist yet and the wizard will help
you defining it.

You must use the shortcut notation like AcmeBlogBundle:Post.

The Entity shortcut name: AppBundle:User

By default, the generator creates two actions: list and show.
You can also ask it to generate "write" actions: new, update, and delete.

Do you want to generate the "write" actions [no]? yes

Determine the format to use for the generated CRUD.

Configuration format (yml, xml, php, or annotation) [annotation]:

Determine the routes prefix (all the routes will be "mounted" under this
prefix: /prefix/, /prefix/new, ...).

Routes prefix [/user]:


  Summary before generation


You are going to generate a CRUD controller for "WorkshopBackendBundle:User"
using the "annotation" format.

Do you confirm generation [yes]?


  CRUD generation


Generating the CRUD code: OK
Generating the Form code: OK


  You can now start using the generated code!
View Code

2:修改controller以下:

<?php

namespace AppBundle\Controller;

use AppBundle\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
/**
 * User controller.
 *
 * @Route("user")
 */
class UserController extends Controller
{
    /**
     * Lists all user entities.
     *
     * @Route("/", name="user_index")
     * @Method("GET")
     * @Template()
     */
    public function indexAction(Request $request)
    {
        $em = $this->getDoctrine()->getManager();
        $query = $em->getRepository('AppBundle:User')
            ->createQueryBuilder('c')
            ->getQuery();
        $paginator  = $this->get('knp_paginator');
        $pagination = $paginator->paginate(
            $query,
            $request->query->getInt('page', 1), 1
        );
        return array(
            'pagination' => $pagination,
        );

    }

    /**
     * Creates a new user entity.
     *
     * @Route("/new", name="user_new")
     * @Method({"GET", "POST"})
     * @Template()
     */
    public function newAction(Request $request)
    {
        $user = new User();
        $user->addRole(User::ROLE_USER);
        $form = $this->createForm('AppBundle\Form\UserType', $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $userManager = $this->get('fos_user.user_manager');
            $userManager->updateUser($user);

            return $this->redirectToRoute('user_show', array('id' => $user->getId()));
        }

        return [
            'user' => $user,
            'form' => $form->createView()
        ];
    }

    /**
     * Finds and displays a user entity.
     *
     * @Route("/{id}", name="user_show")
     * @Method("GET")
     * @Template()
     */
    public function showAction(User $user)
    {
        $deleteForm = $this->createDeleteForm($user);

        return [
            'user' => $user,
            'delete_form' => $deleteForm->createView(),
        ];
    }

    /**
     * Displays a form to edit an existing user entity.
     *
     * @Route("/{id}/edit", name="user_edit")
     * @Method({"GET", "POST"})
     * @Template()
     */
    public function editAction(Request $request, User $user)
    {
        $deleteForm = $this->createDeleteForm($user);
        $editForm = $this->createForm('AppBundle\Form\UserType', $user);
        $editForm->handleRequest($request);

        if ($editForm->isSubmitted() && $editForm->isValid()) {
            $this->getDoctrine()->getManager()->flush();

            return $this->redirectToRoute('user_show', array('id' => $user->getId()));
        }

        return [
            'user' => $user,
            'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        ];
    }

    /**
     * Deletes a user entity.
     *
     * @Route("/{id}", name="user_delete")
     * @Method("DELETE")
     */
    public function deleteAction(Request $request, User $user)
    {
        $form = $this->createDeleteForm($user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->remove($user);
            $em->flush();
        }

        return $this->redirectToRoute('user_index');
    }

    /**
     * Creates a form to delete a user entity.
     *
     * @param User $user The user entity
     *
     * @return \Symfony\Component\Form\Form The form
     */
    private function createDeleteForm(User $user)
    {
        return $this->createFormBuilder()
            ->setAction($this->generateUrl('user_delete', array('id' => $user->getId())))
            ->setMethod('DELETE')
            ->getForm()
        ;
    }


    /**
     * enable
     * @Route("/{id}/enable", name="user_enable")
     * @Method("GET")
     */
    public function enableAction(Request $request,User $user)
    {
        $userManager = $this->get('fos_user.user_manager');
        $user->setEnabled(true);
        $userManager->updateUser($user);
        $this->addFlash('success', '已經啓用');
        return $this->redirectToRoute('user_show', array('id' => $user->getId()));
    }

    /**
     * disable a Member entity.
     *
     * @Route("/{id}/disable", name="user_disable")
     * @Method("GET")
     */
    public function disableAction(Request $request, User $user)
    {
        $userManager = $this->get('fos_user.user_manager');
        $user->setEnabled(false);
        $userManager->updateUser($user);
        $this->addFlash('success', '已經禁用'
        );
        return $this->redirectToRoute('user_show', array('id' => $user->getId()));
    }


}
View Code

3:CRUD的html頁面以下:

index

{% extends "AppBundle:layout:admin.layout.html.twig" %}

{% block title %}管理控制檯{% endblock %}

{% block main %}
    <ol class="breadcrumb clearfix">
        <li><a href="{{ path('user_index') }}">用戶管理</a></li>
        <li class="pull-right">
            <a href="{{ path('user_new' ) }}">新建</a>
        </li>
    </ol>

    <table class="table">
        <thead>
        <tr>
            <th>ID</th>
            <th>用戶名</th>
            <th>郵箱</th>
            <th>角色</th>
            <th>狀態</th>
            <th>最後登陸</th>
            <th>操做</th>
        </tr>
        </thead>
        <tbody>
        {% for user in pagination %}
            <tr>
                <td><a href="{{ path('user_show', { 'id': user.id }) }}">{{ user.id }}</a></td>
                <td>{{ user.username }}</td>
                <td>{{ user.email }}</td>
                <td>
                    <ul class="list">
                        {%for role in user.roles %}
                            <li>{{role}}</li>
                        {%endfor%}
                    </ul>
                </td>
                <td>
                    {% if user.enabled %}
                        <span class="label label-success">啓用</span>
                    {% else %}
                        <span class="label label-danger">禁用</span>
                    {% endif %}
                </td>
                <td>{{ user.lastLogin |date('Y-m-d H:i') }}</td>
                <td>
                    <a href="{{ path('user_show', { 'id': user.id }) }}">查看</a>
                    <a href="{{ path('user_edit', { 'id': user.id }) }}">編輯</a>
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
    {{ knp_pagination_render(pagination, "KnpPaginatorBundle:Pagination:twitter_bootstrap_v3_pagination.html.twig") }}

{% endblock %}
View Code

new

{% extends "AppBundle:layout:admin.layout.html.twig" %}

{% block title %}管理控制檯{% endblock %}

{% block main %}
    <ol class="breadcrumb clearfix">
        <li><a href="{{ path('user_index') }}">用戶管理</a></li>
        <li class="pull-right">
            <a href="{{ path('user_index') }}">列表</a>
        </li>
    </ol>
    {{ form_start(form) }}
    {{ form_widget(form) }}
    <input type="submit" value="保存" class="btn btn-primary" />
    {{ form_end(form) }}
{% endblock %}
View Code

edit

{% extends "AppBundle:layout:admin.layout.html.twig" %}

{% block title %}管理控制檯{% endblock %}

{% block main %}
    <ol class="breadcrumb clearfix">
        <li><a href="{{ path('user_index') }}">用戶管理</a></li>
        <li class="pull-right">
            <a href="{{ path('user_edit',{'id':user.id} ) }}">編輯</a>
        </li>
    </ol>
    {{ form_start(edit_form) }}
    {{ form_widget(edit_form) }}
    <input type="submit" value="保存" class="btn btn-primary" />
    {{ form_end(edit_form) }}
{% endblock %}
View Code

show

{% extends "AppBundle:layout:admin.layout.html.twig" %}

{% block title %}管理控制檯{% endblock %}

{% block main %}
    <ol class="breadcrumb clearfix">
        <li><a href="{{ path('user_index') }}">用戶管理</a></li>
        <li class="pull-right">
            <a href="{{ path('user_edit',{'id':user.id} ) }}">編輯</a>
        </li>
    </ol>
    <table class="table">
        <tbody>
        <tr>
            <th>Id</th>
            <td>{{ user.id }}</td>
        </tr>
        <tr>
            <th>用戶名</th>
            <td>{{ user.username }}</td>
        </tr>
        <tr>
            <th>郵箱</th>
            <td>{{ user.email }}</td>
        </tr>
        <tr>
            <th>狀態</th>
            <td>{{ user.enabled }}</td>
        </tr>
        <tr>
            <th>最後登錄時間</th>
            <td>{{ user.lastLogin|date('Y-m-d H:i:s') }}</td>
        </tr>


        <tr>
            <th>Roles</th>
            <td>
                <ul class="list">
                    {%for role in user.roles %}
                        <li>{{role}}</li>
                    {%endfor%}
                </ul>
            </td>
        </tr>

        </tbody>
    </table>
    <div class="clearfix">
        <div class="pull-right">
            {% if user.enabled %}
                <a class="btn btn-danger btn_delete" onclick="return confirm('肯定禁用?')"
                   href="{{ path('user_disable', { 'id': user.id }) }}">禁用</a>
            {% else %}
                <a class="btn btn-success" onclick="return confirm('肯定啓用?')"
                   href="{{ path('user_enable', { 'id': user.id }) }}">啓用
                </a>
            {% endif %}
        </div>
    </div>
{% endblock %}
View Code

4:創建權限—修改security.yml

# app/config/security.yml
security:
    encoders:
        FOS\UserBundle\Model\UserInterface: bcrypt

    role_hierarchy:
        ROLE_BLOG:         ROLE_USER
        ROLE_ADMIN:        ROLE_BLOG
        ROLE_PENG:         [ROLE_ADMIN,ROLE_BLOG]
    providers:
        fos_userbundle:
            id: fos_user.user_provider.username

    firewalls:
        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
#                csrf_provider: security.csrf.token_manager
                csrf_token_generator: security.csrf.token_manager
                remember_me: true
                default_target_path: /admin
            remember_me:
                always_remember_me: true
                lifetime: 2592000 #month
                secret: "%secret%"
            logout:       true
            anonymous:    true


    access_control:
        - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
#        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
#        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
#        - { path: ^/admin/,         roles: ROLE_ADMIN }
        - { path: ^/admin/blog/,         roles: ROLE_USER }
        - { path: ^/admin/user/,         roles: ROLE_PENG }
        - { path: ^/, role: IS_AUTHENTICATED_ANONYMOUSLY }
View Code

5:給user實體添加驗證,不要忘了use導入:

<?php

namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;


/**
 * @ORM\Entity
 * @ORM\Table(name="dream_user")
 * @UniqueEntity("username",message="用戶名已經存在")
 * @UniqueEntity("email",message="郵箱已經存在")
 */
class User extends BaseUser
{
    const ROLE_USER      = 'ROLE_USER';//平臺用戶
    //構造函數
    public function __construct()
    {
        parent::__construct();
        $this->addRole(self::ROLE_USER);
        $this->setEnabled(true);
        // your own logic
    }

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;



}
View Code

到此爲止,用戶管理,以及權限劃分已經完成;

我如今須要從新寫一個登錄頁面:

1:

首先加入一個bootstrap.layout.html.twing佈局樣式,   登錄頁 login.html.twing;

2:添加RegisterLoginController.php; 代碼以下:

<?php

namespace WebBundle\Controller;


use SensioLabs\Security\SecurityChecker;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Core\Security;


class RegisterLoginController extends Controller
{

    /**
     * @Route("/login", name="Blog_Login")
     * @Method({"GET","POST"})
     * @Template()
     */
    public function loginAction(Request $request)
    {
        $param =  array();
        $securityChecker = $this->get('security.authorization_checker');
        if($securityChecker->isGranted('IS_AUTHENTICATED_FULLY')){
            //已登陸
//            return $this->redirectToRoute('homepage');
        }

        if($request->getMethod()==='POST'){
            $username = $request->request->get('username');
            $plainPassword = $request->request->get('password');
            $em = $this->getDoctrine()->getManager();
            $member = $em->getRepository('AppBundle:User')
                ->findOneBy(['username'=>$username]);
            $encoder = $this->get('security.password_encoder');

            if($member&&$encoder->isPasswordValid($member,$plainPassword)){
                //成功登陸
                $loginManager = $this->get('fos_user.security.login_manager');
                $response = new RedirectResponse($this->generateUrl('homepage'),301);
                $member->setLastLogin(new \DateTime());
                $em->persist($member);
                $em->flush();
                $loginManager->logInUser('main',$member,$response);
                return $response;
            }else{
                //failure
                $this->addFlash(
                    'danger',
                    '身份驗證失敗,請檢查用戶名與密碼'
                );
            }
        }
        return $param;
    }





}
View Code

3:<a class="page-scroll" href="{{path('Blog_Login')}}">登陸</a>

完成一個登錄頁面,樣式能夠調整,我使用的是Bootstartp;

------------------------------------------------------------------------------------------------

到此爲止,基本框架均可以,如需調整就是細節調整了,那麼如今就開始寫最重要的

文章發佈;前臺頁面;

------------------=================-------------------------

後臺文章發佈

前臺頁面展現:

如今要寫前臺頁面:

 

1)創建基本 bootstrapLayout.html.twig

 

 
<!DOCTYPE html>
<html lang="zh_CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>{% block title %}{% endblock %}</title>

    <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">

    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

</head>
<body>
{%block body%}
    {%block header%}{%include "WebBundle:Common:_header.html.twig"%}{%endblock%}
    <div class="container main-content">
        {%block main%}
        {%endblock%}
    </div>
    {%block footer%}{%include "WebBundle:Common:_footer.html.twig"%}{%endblock%}
{%endblock%}
</body>
</html>
View Code

 

2) 創建基本 Sidebar Layout

 src/WebBundle/Resources/views/Layout/sidebarLayout.html.twig

 {%extends "WebBundle:Layout:bootstrapLayout.html.twig"%}

{%block header%}{%include "WorkshopFrontendBundle:Common:_header.html.twig"%}{%endblock%}
{%block footer%}{%include "WorkshopFrontendBundle:Common:_footer.html.twig"%}{%endblock%}

{%block main%}
<div class="row">
<div class="col-md-3" style="border: 1px solid;height: 300px;">sidebar</div>
<div class="col-md-9" role="main">{%block content%}{%endblock%}</div>
</div>
{%endblock%}

 

接着設定好前臺的 header 跟 footer
 
src/WebBundle/Resources/views/Common/_header.html.twig
<header role="header">
<div class="page-header">
<h1>Example page header <small>Subtext for header</small></h1>
</div>
</header>
src/WebBundle/Resources/views/Common/_footer.html.twig
<footer role="footer" class="bs-footer">
<div class="container text-center">
This is footer.
</div>
</footer>

3) 首頁顯示目前全部文章的列表
 
透過 Doctrine Entity Manager 讀出全部文章。

src/WebBundle/Controller/DefaultController.php
<?php

namespace WebBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class DefaultController extends Controller
{
    /**
     * @Route("/",name="welcome")
     * @Template()
     */
    public function indexAction()
    {
        $em = $this->getDoctrine()->getManager();
        $posts = $em->getRepository('AppBundle:Post')
            ->findBy(array(), array('id' => 'desc'));
        return array('posts'=>$posts);
    }
}
View Code

  爲了方便共用文章列表,咱們將文章列表抽出獨立成一個 partial view。

 
src/WebBundle/Resources/views/Post/_list.html.twig
 
{%for post in posts%}
<div class="page-header">
<h1>{{post.subject}} <small>{{post.createdAt|date('Y-m-d H:i:s')}}</small></h1>
</div>
<p>{{post.content}}</p>
{%endfor%}


4) 設定 Sidebar 內容,顯示全部的分類目錄
 
創建一個 Category Controller 修改sidebar 內容
<?php

namespace WebBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use AppBundle\Entity\Category;
use AppBundle\Entity\Post;
use Symfony\Component\HttpFoundation\Request;

/**
 * @Route("/category")
 */
class CategoryController extends Controller
{
    /**
     * @Template()
     */
    public function _categoryAction(Request $request)
    {
        $currentCategory = $request->get('currentCategory');
        $em = $this->getDoctrine()->getManager();
        $categories = $em->getRepository('AppBundle:Category')
            ->createQueryBuilder('c')
            ->orderBy('c.id', 'asc')
            ->getQuery()
            ->getResult();
        return array('categories' => $categories, 'currentCategory' => $currentCategory);
    }


    /**
     * @Route("/{id}-{name}", name="@categoryIndex")
     * @Template()
     */
    public function indexAction(Category $category)
    {
        $em = $this->getDoctrine()->getManager();
        $posts = $em->getRepository('AppBundle:Post')
            ->findBy(array('category' => $category), array('id' => 'desc'));
        return array('category' => $category, 'posts' => $posts);
    }

}
View Code
{%if currentCategory is not defined%}
    {%set currentCategory = null%}
{%endif%}
{%extends "WebBundle:Layout:bootstrapLayout.html.twig"%}
{%block title %}個人博客 | dreamstart{% endblock %}
{%block header%}{%include "WebBundle:Common:_header.html.twig"%}{%endblock%}
{%block footer%}{%include "WebBundle:Common:_footer.html.twig"%}{%endblock%}

{%block main%}
    <div class="row">
        <div class="col-md-3">{{ render(controller("WebBundle:Category:_category",{currentCategory: currentCategory}))}}</div>
        <div class="col-md-9" role="main">{%block content%}{%endblock%}</div>
    </div>
{%endblock%}
View Code

 

修改src/WebBundle/Resources/views/Category/_category.html.twig

<ul style="max-width: 300px;" class="nav nav-pills nav-stacked">
{%for category in categories%}
<li{%if currentCategory and currentCategory.id == category.id%} class="active"{%endif%}><a href="{{path('@categoryIndex', {id: category.id, name: category.name})}}">{{category.name}}</a></li>
{%endfor%}
</ul>

修改src/WebBundle/Resources/views/Category/index.html.twig

{%extends "WebBundle:Layout:sidebarLayout.html.twig"%}
{%set currentCategory = category%}
{% block content %}
{%include "WebBundle:Post:_list.html.twig" with {posts: posts}%}
{% endblock %}
  

 

 

創建一個PostController

<?php
/**
 * Created by PhpStorm.
 * User: peng
 * Date: 2017/5/7
 * Time: 23:51
 */

namespace WebBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use AppBundle\Entity\Post;

/**
 * @Route("/post")
 */
class PostController extends Controller
{
    /**
     * @Route("/{id}-{name}.html", name="@postView")
     * @Template()
     */
    public function viewAction(Post $post)
    {
        return array('post' => $post);
    }

}
View Code

  修改src/WebBundle/Resources/views/Post/_list.html.twig

 
{%for post in posts%}
<div class="page-header">
<a href="{{path('@postView', {id: post.id, name: post.name})}}"><h1>{{post.name}} <small>{{post.created|date('Y-m-d H:i:s')}}</small></h1></a>
</div>
<p>{{post.content}}</p>
{%endfor%}


src/WebBundle/Resources/views/Post/view.html.twig

 

{%extends "WebBundle:Layout:sidebarLayout.html.twig"%}

{% block content %}
<div class="page-header">
<a href="{{path('@postView', {id: post.id, name: post.name})}}"><h1>{{post.name}} <small>{{post.created|date('Y-m-d H:i:s')}}</small></h1></a>
</div>
<p>{{post.content|nl2br}}</p>
{% endblock %}
到此前臺文章列表,分類類別,點擊分類都已實現;
----------------------------------------------------------------------------------
如今我添加了一個評論功能,
須要所有代碼的能夠掃上面微信也
能夠關注我另外一個微信公衆號Coding手藝人,微信號:coding_craftsman
---------------------------------------------------------
接下來我須要寫一個圖片上傳功能,在文章裏添加圖片
1:修改 Post Entity
use Symfony\Component\HttpFoundation\File\UploadedFile;
如下是文件上傳部分代碼:
  /**
     *
     * @var UploadedFile
     */
    protected $file;

    /**
     * @var string
     *
     * @ORM\Column(name="filename", type="string", length=255, nullable=true)
     */
    private $filename;

    protected function getUploadRootDir()
    {
        return realpath(__DIR__.'/../../../../../web').'/'.$this->getUploadDir();
    }
    protected function getUploadDir()
    {
        return 'uploads/images';
    }
    public function getWebPath()
    {
        if($this->filename === null){
            return null;
        }

        return $this->getUploadDir().'/'.$this->filename;
    }

    public function getAbsolutePath()
    {
        if($this->filename === null){
            return null;
        }
        return $this->getUploadRootDir().'/'.$this->filename;
    }

    public function setFile(UploadedFile $file = null)
    {
        $this->file = $file;
    }
    /**
     *
     * @return UploadedFile
     */
    public function getFile()
    {
        return $this->file;
    }

    public function upload()
    {
        if($this->file === null){
            return;
        }

        if(!file_exists($this->getUploadRootDir())){
            mkdir($this->getUploadRootDir(), 0777, true);
        }

        $this->filename = "{$this->getId()}.{$this->getFile()->guessExtension()}";

        $this->getFile()->move($this->getUploadRootDir(), $this->filename);

        $this->setFile(null);
    }

//文件上穿部分代碼結束
View Code
相關文章
相關標籤/搜索