Practical symfony Day 12: The Admin Generator Орчуулсан Б.Батжаргал

English source: http://www.symfony-project.org/jobeet/1_4/Doctrine/en/12

Орчуулсан:

Б.Батжаргал
b.batja@gmail.com
http://ssacci.blogspot.com

Дурьдатгал:

Олны хүч оломгүй далай гэгчээр бидний орчуулгын хэсэгт маань Б.Батжаргал гишүүн өөрийн хүчээ хавсаргалаа.  Таньд энэ хичээл таалагдсан бол Батжаргалд баярлалаа гээрэй.

Энэхүү админ үүсгэгч нь symfony framework байдаг том давуу талуудын нэг бөгөөд маш хэрэгтэй сэдвүүдийн нэг яалтчгүй мөн юм. Үүний ачаар та өөрийн прожектынхоо админы хэсгийг яаж үүсгэхэд санаа зовох шаардлагагүй боллоо гэсэн үг.

Асуух зүйл байвал comment үлдээгээрэй эсвэл mongolian-symfony-users@googlegroups.com -группын гишүүдээс асуух боломжтой.

Энэхүү номыг монгол хэлээр хөрвүүлөх ажилд маань оролцож буй бүх гишүүддээ БАЯРЛАЛАА. Номын буян дэлгэрэх болтугай.

Day 12: The Admin Generator (Өдөр 12: Админ үүсгэгч)

Бид jobeet –ийн 11 өдөрийн турш ажил нийтлэх болон ажил хайх frontend application хийсэн билээ. Одоо backend application –ны талаар бага зэрэг ярья. Өнөөдөр, Jobeet –ийн backend интерфэйсийг хөгжүүлэхэд нэгхэн цаг л хангалттай бөгөөд бид symfony –ийн админ үүсгэгч функцтэй танилцах болно.

Backend creation (Backend байгуулалт)

Хамгийн эхний алхам нь backend application үүсгэх юм. Хэрвээ та сайн ой тогтоолттой бол, generate:app комманд (task) –ыг хэрхэн ашигладагийг санаж байгаа байгаа байх.

$ php symfony generate:app backend

Одоо backend application–ны бүтээгдэхүүний орчин (prod environment) http://jobeet.localhost/backend.php/ болон хөгжүүлэлтийн орчин (dev environment) http://jobeet.localhost/backend_dev.php/ бэлэн болсон.

v  Frontend application үүсгэх үед, бүтээгдэхүүний front  controller нь index.php нэртэй байсан. Фолдер (directory) бүрт index.php файл зөвхөн нэг байх ёстой тул symfony хамгийн эхний бүтээгдэхүүний (production) front controller –т index.php файл үүсгэдэг ба дараагийн файлуудыг application –ны нэрээр нэрлэдэг.

Хэрэв data fixtures –ийг doctrine:data-load коммандаар дахин үүсгэхийг оролдвол, энэ нь ажиллахгүй юм. Учир нь, JobeetJob::save() функц (method) нь frontend application –aac app.yml configuration файл руу хандна. Одоо бидэнд хоёр application байгаа, эхнийх нь symfony –ийн ашиглаж байгаа frontend application, хоёрдах нь backend application юм.

Бид тохиргоонууд (settings) нь өөр өөр түвшинд тохируулагддаг гэдгийг 8 –н өдрийн турш үзсэн билээ.  apps/frontend/config/app.yml файлын кодыг (content) config/app.yml файл руу зөөснөөр тохиргоонууд нь бүх application –уудын хувьд идэвхижих ба асуудал (problem) засагдана. Одоо admin generator –т model классуудыг ашиглах мөн backend application-ны app.yml файлд хувьсагчуудыг тодорхойлох өөрчлөлтийг хийе.

v  Хэрэв нэг эсвэл өөр application –аас зарим тусгай тохиргоонууд хэрэгтэй бол doctrine:data-load коммандын --application боломж (option) –ийг тавина.

$ php symfony doctrine:data-load --application=frontend

Backend Modules (backend модулиуд)

Frontend application –ны хувьд doctrine:generate-module комманд үндсэн CRUD модульд суурилагдсан Model классдээр bootstrap –ийг ашигласан. Backend application –ны хувьд Model класс-ийн backend интерфэйс үүсгэхэд doctrine:generate-admin коммандыг хэрэглэнэ.

$ php symfony doctrine:generate-admin backend JobeetJob --module=job
$ php symfony doctrine:generate-admin backend JobeetCategory --module=category

Дээрхи коммандууд нь  JobeetJob болон JobeetCategory model (загвар) классуудад харгалзан job болон category module (модуль) үүсгэнэ.

--module боломж (option)–ийг тодорхойлж өгсөнөөр коммандын default –аар үүсгэсэн модулийн нэрийг солино. (хэрэв тодорхойлоогүй бол JobeetJob –ийн хувьд үүссэн модуль нь jobeet_job нэртэй байна.)

Арын хэсгүүд, комманд нь мөн модуль бүрийн custom route (чиглүүлэгч хэв) – г үүсгэдэг.

 
# apps/backend/config/routing.yml
jobeet_job:
  class: sfDoctrineRouteCollection
  options:
    model:                JobeetJob
    module:               job
    prefix_path:          job
    column:               id
    with_wildcard_routes: true

Admin generator –т хэрэглэгдэж байгаа route -н класс нь санамсаргүй зүйл биш юм. (Admin Generator бол sfDoctrineRouteCollection юм.) Админ интерфэйсийн гол зорилго нь model (загвар) обьектуудын ажиллах циклийн менежмент (management of the life-cycle) юм.

Дээрхи route тодорхойлолтонд түүнчлэн бидний өмнө нь үзээгүй хэдэн боломжууд (options) –ыг тодорхойлсон байна.

  • · prefix_path: route (чиглүүлэгч) үүсгэх угтвар замыг тодорхойлдог(жишээ нь, засварлах хуудас нь /job/1/edit шиг байж болно).
  • · column: обьектыг лавлах холбоосуудын URL-д хэрэглэх хүснэгтийн баганыг тодорхойлно.
  • with_wildcard_routes:  Админ интерфэйс нь сонгодог (classic) CRUD үйлдлүүдээс илүү боломжуудтай. Энэ боломж (option) нь  route –ийг засварлахгүйгээр олон обьект болон action –ны цуглуулга (collection) тодорхойлохыг зөвшөөрдөг.

v  Шинэ комманд (task) хэрэглэхийн өмнө үргэл тусламж (help) –ийг уншиж байх нь сайн зуршил (good idea) юм.

 
$ php symfony help doctrine:generate-admin
 
Энэ нь чамд коммандын бүх аргументууд блон бололмжууд(options)-ийг мөн дээр нь хэрхэн ашиглах зарим сонгодог жишээнүүдийг харуулах болно.
 
 

Backend Look and Feel (backend харагдац болон ойлголт)

 
Нүд ирмэх зуур л модулиудаа үүсгэлээ. Одоо ашиглаж болно:
 
http://jobeet.localhost/backend_dev.php/job
http://jobeet.localhost/backend_dev.php/category
 
Админ модулиуд (modules) нь бидний өмнөх өдрүүдэд үүсгэсэн энгийн модулиудаас (modules) илүү олон онцлогуудтай. PHP –н нэг ч мөр бичилгүйгээр модуль (module) бүр дараах олон онцлогуудаар хангагддаг:
·         Обьектуудын жагсаалт нь хуудаслагдсан ( paginated ). 
·         Жагсаалт нь эрэмблэлттэй ( sortable ). 
·         Жагсаалтаас шүүлт хийнэ ( filtered ) . 
·         Обьектууд үүсгэж, засварлаж, устгаж болно. ( created, edited, and deleted ) 
·         Сонгосон обьектуудыг batchаас устгах.
·         Формын оролт шалгалт ( form validation ) идэвхижсэн.
·         Хэрэглэгч руу шууд feedback (мэдэгдэх)  өгөх flash messages
·         ... болон илүү олон 
 
Admin generator нь backend интерфэйс үүсгэхэд хэрэгтэй энгийн тохиргооны пакеж (configure package) дахь бүх онцлогуудаар хангадаг.

Үүсгэгдсэн хоёр модулиудыг хараад, webdesign идэвхижээгүй байхад symfony үндсэн график интерфэйсийг default –аар үүсгэсэн байгааг чи ажигласан байх. Одоо sfDoctrinePlugin –н файлууд (assets - хөрөнгө) web/ фолдерт байрлаагүй байгаа ба бид plugin:publish-assets коммандыг хэрэглэн web/ фолдерт тэдгээрийг байрлуулана:

$ php symfony plugin:publish-assets

Хэрэглэгчийн чадварыг бага зэрэг нэмэгдүүлэх үүднээс default backend –ийг өөрчлөх хэрэгтэй. Мөн өөр модуль хооронд шилжихэд (navigate)  хялбар болгох энгийн цэс (menu) нэмнэ.

layout файлын агуулгыг доорхи кодоор соль (replace):

// apps/backend/templates/layout.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Jobeet Admin Interface</title>
    <link rel="shortcut icon" href="/favicon.ico" />
    <?php use_stylesheet('admin.css') ?>
    <?php include_javascripts() ?>
    <?php include_stylesheets() ?>
  </head>
  <body>
    <div id="container">
      <div id="header">
        <h1>
          <a href="<?php echo url_for('homepage') ?>">
            <img src="/images/logo.jpg" alt="Jobeet Job Board" />
          </a>
        </h1>
      </div>

      <div id="menu">
        <ul>
          <li>
            <?php echo link_to('Jobs', 'jobeet_job') ?>
          </li>
          <li>
            <?php echo link_to('Categories', 'jobeet_category') ?>
          </li>
        </ul>
      </div>

      <div id="content">
        <?php echo $sf_content ?>
      </div>

      <div id="footer">
        <img src="/images/jobeet-mini.png" />
        powered by <a href="http://www.symfony-project.org/">
        <img src="/images/symfony.gif" alt="symfony framework" /></a>
      </div>
    </div>
  </body>
</html>

Энэ layout (давхарга) нь admin.css stylesheet (загвар хуудас) хэрэглэдэг. Энэ файлыг 4 дэхь өдөр бусад stylesheet  -уудтай хамт web/css/ фолдерт хуулсан (installed) байгаа.

Эцэст нь, routing.yml файл дахь symfony homepage –ийг өөрчилнө:

# apps/backend/config/routing.yml
homepage:
  url:   /
  param: { module: job, action: index }

The symfony Cache (symfony кэйш)

Их сониуч хүн бол магадгүй аль хэдийн коммандаар apps/backend/modules/ директорт үүссэн файлуудыг нээчихсэн байгаа байх.  Үгүй бол одоо тэднийг нээнэ үү. Surprise! templates директорууд хоосон байгаа ба actions.class.php файлууд бараг хоосон байна:

// apps/backend/modules/job/actions/actions.class.php
require_once dirname(__FILE__).'/../lib/jobGeneratorConfiguration.class.php';
require_once dirname(__FILE__).'/../lib/jobGeneratorHelper.class.php';

class jobActions extends autoJobActions
{
}

Яаж ажиллаж байна вэ? Хэрвээ чи сайн харах юм бол, jobActions класс autoJobActions классаас удамшсан (extends)  байгааг мэдэх болно. Хэрэв autoJobActions класс байхгүй бол symfony автоматаар үүсгэдэг. autoJobActions классыг cache/backend/dev/modules/autoJob/ директороос олж болно. Энэ нь “real&#8221; модулийг агуулдаг:

// cache/backend/dev/modules/autoJob/actions/actions.class.php
class autoJobActions extends sfActions
{
  public function preExecute()
  {
    $this->configuration = new jobGeneratorConfiguration();

    if (!$this->getUser()->hasCredential(
      $this->configuration->getCredentials($this->getActionName())
    ))
    {

// ...

Admin  generator  нь зарим төлөв байдлыг сануулах замаар ажилдаг. Бид үнэндээ ийм model болон форм классуудын тухай аль хэдийн сурчихсан. Symfony model тодорхойлсон схем дээр суурилж model болон форм классуудыг үүсгэдэг.  Admin generator –ийн хувьд үүсгэгдсэн модулийг модуль дахь config/generator.yml файлыг засварлаж тохируулга хийнэ:

# apps/backend/modules/job/config/generator.yml
generator:
  class: sfDoctrineGenerator
  param:
    model_class:           JobeetJob
    theme:                 admin
    non_verbose_templates: true
    with_show:             false
    singular:              ~
    plural:                ~
    route_prefix:          jobeet_job
    with_doctrine_route:   true

    config:
      actions: ~
      fields:  ~
      list:    ~
      filter:  ~
      form:    ~
      edit:    ~
      new:     ~

generator.yml файлыг засварлах бүр symfony кэш (cache) үүсгэж байдаг. Бид дараа админы үүсгэгдсэн модулиудыг засаж өөрчлөх нь амархан, хурдан бөгөөд хөгжилтэй ажил болохыг харах болно.

v  Автоматаар дахин үүсгэсэн кэш файлууд нь зөвхөн хөгжүүлэлтийн орчинд (development environment) харагддаг. Харин бүтээгдэхүүний орчинд (production environment) cache:clear коммандыг ажиллуулж кэшийг устгах хэрэгтэй.

with_show параметр нь ямарч нөлөөгүй (no effect) юм. Энэ параметр нь зөвхөн doctrine:generate-module комманд “standard&#8221;  модулиуд үүсгэж байна гэсэн утгатай.

Backend Configuration (backend тохиргоо)

generator.yml файлын config түлхүүрийг засварласанаар админ модулийг өөрчилнө.  Энэ тохиргоо нь долоон хэсгээс бүтнэ:

  • actions: жагсаалт (list) болон фомрын action –нуудын default тохиргоо
  • fields: талбаруудын default тохиргоо
  • list: жагсаалтын (list) тохиргоо
  • filter: шүүлтийн (filter) тохиргоо
  • form: шинээр үүсгэх болон завсарлах формуудын тохиргоо
  • edit: засварлах хуудасны тохиргоо тодорхойлох
  • new: шинээр үүсгэх хуудасны тохиргоо тодорхойлох

Өөрчлөлтөө эхэлцгээе!

Title Configuration (гарчигны тохиргоо)

Title боломж (option)-ийг тодорхойлсоноор category модулийн жагсаалт (list), засварлах ( edit), болон шинээр үүсгэх (new) хэсгүүдийн гарчигийг өөрчилж болно:

# apps/backend/modules/category/config/generator.yml
config:
  actions: ~
  fields:  ~
  list:
    title: Category Management
  filter:  ~
  form:    ~
  edit:
    title: Editing Category "%%name%%"
  new:
    title: New Category

Засварлах (edit) хэсгийн title -д динамик утга авдаг: %% тэмдэгийн хооронд обьектын тохирох баганы утгыг тавьж өгнө.

job модулийн тохиргоо нь яг адилхан:

# apps/backend/modules/job/config/generator.yml
config:
  actions: ~
  fields:  ~
  list:
    title: Job Management
  filter:  ~
  form:    ~
  edit:
    title: Editing Job "%%company%% is looking for a %%position%%"
  new:
    title: Job Creation

Fields Configuration (талбаруудын тохиргоо)

Харагдац бүрийн (list, new, болон edit) талбарууд өөр зохион байгуулалттай. Талбар нь model классын багана эсвэл virual  багана байна. Virtual баганыг дараа үзнэ.

Талбаруудын default тохиргоог fields хэсэгт өөрчилнө:

# apps/backend/modules/job/config/generator.yml
config:
  fields:
    is_activated: { label: Activated?, help: Whether the user has activated the job, or not }
    is_public:    { label: Public?, help: Whether the job can also be published on affiliate websites, or not }

fields хэсэг дэхь is_activated талбарын label нь бүх (list, edit, болон new) харагдацын тохиргоог өөрчилнө.

Admin generator тохиргоо нь cascade зарчим дээр суурилагдсан. Тухайлбал, хэрэв та зөвхөн list харагдацын label –г өөрчлөхийг хүсвэл list хэсэгт fields боломж (option)-г тодорхойлох хэрэгтэй:

# apps/backend/modules/job/config/generator.yml
config:
  list:
    fields:
      is_public:    { label: "Public? (label for the list)" }

Үндсэн fields хэсэгт тавьсан ямарч тохиргооноос (configuration) харагдацад тодорхойлсон тохиргоо нь давуу байна.  Доор давуу зэргийн зарчимыг харуулсан байна:

  • new болон edit нь form -оос удамшсан. form нь fields –ээс удамшсан.
  • list нь fields –ээс удамшсан
  • filter нь fields ээс удамшсан

v  form (form, edit, болон new) хэсгүүдийн хувьд label болон help боломж (option) -ууд form классуудад тодорхойлсоныг дахин тодорхойлдог.

List View Configuration (жагсаалт харагдацын тохиргоо)

display (харуулах)

default –аар list харагдацын баганууд нь схем файлд (schema file)  тодорхойлсон model –ийн бүх баганууд байдаг. display боломж (option) нь дэлгэцэнд харагдах багануудыг дахин тодорхойлдог:

# apps/backend/modules/category/config/generator.yml
config:
  list:
    title:   Category Management
    display: [=name, slug]

баганын name –ын өмнө = тэмдэг байгаа нь тэмдэг мөрийг холбоос руу хөрвүүлэхийг заана.

Одоо job модулийг мөн адил уншихад илүү хялбар болгоцгооё:

# apps/backend/modules/job/config/generator.yml
config:
  list:
    title:   Job Management
    display: [company, position, location, url, is_activated, email]

layout (давхарга)

list –ийг өөр давхаргуудаар (layouts) харуулж болно. Default –аар tabular давхаргаар (layout) харагддаг ба энэ нь багана бүрийн утга өөрийн хүснэгтийн баганад харагдана гэсэн үг. Гэвч job модулийн хувьд stacked давхарга (layout) –ыг хэрэглэсэн нь бусад давхарга (layout) –аар хийхээс илүү дээр юм:

# apps/backend/modules/job/config/generator.yml
config:
  list:
    title:   Job Management
    layout:  stacked
    display: [company, position, location, url, is_activated, email]
    params:  |
      %%is_activated%% <small>%%category_id%%</small> - %%company%%
       (<em>%%email%%</em>) is looking for a %%=position%% (%%location%%)

stacked давхарга (layout) нь обьект бүрийг params боломж (option) –д тодорхойлсоноор нэг тэмдэгт мөрөөр харуулдаг.

display боломж (option) нь хэрэглэгчийн эрэмлэлт хийх багануудад хүртэл хэрэглэгддэг.

“Virtual&#8221; columns (хийсвэр багана)

Virtual column тохиргооны %%category_id%% хэсэг категорийн (category) primary key –ээр солигдоно. Энэ нь категорийн нэрийг илүү утга агуулгатай харагдуулна.

Та хэзээ ч юм %% тэмдэглэл хэрэглэж байхдаа  хувьсагчийг нь database schema дэхь жинхэнэ баганыг тохируулахад хэрэглэгддэггүй байсан байх. Admin generator нь зөвхөн model класс дахь холбоотой getter –г олоход хэрэглэнэ.

%%category_id%% -ийг %%category_name%% -ээр сольсоноор JobeetJob model классын getCategoryName() функц категорийн нэрийг харуулах болно.

Гэхдээ JobeetJob класст харгалзах category обьектыг буцаадаг getJobeetCategory() функц аль хэдийн зарлагдсан байгаа. Хэрэв та %%jobeet_category%% гэж хэрэглэвэл JobeetCategory класс дахь шидэт (magic) __toString() функц обьектыг тэмдэгт мөр рүү хөрвүүлсэнээр ажиллах болно.

# apps/backend/modules/job/config/generator.yml
%%is_activated%% <small>%%jobeet_category%%</small> - %%company%%
 (<em>%%email%%</em>) is looking for a %%=position%% (%%location%%)

sort (эрэмбэлэх)

Хэрэв та администратор байсан бол магадгүй хамгийн сүүлд зарлагдсан ажлуудыг харахыг илүү хүсэх байсан байх. sort боломж (option) –ийг нэмснээр эрэмбэлэгдсэн баганыг default –аар тохируулах болно:

# apps/backend/modules/job/config/generator.yml
config:
  list:
    sort: [expires_at, desc]

max_per_page (хуудасанд харагдах хэмжээ)

жагсаалт (list) нь хуудаслагдсан бөгөөд default –аар хуудса бүрт 20 зүйл (item) байна. Үүнийг max_per_page боломж (option) –оор өөрчилнө:

# apps/backend/modules/job/config/generator.yml
config:
  list:
    max_per_page: 10

batch_actions (багцын үйлдлүүд)

Жагсаалт дах action нь зарим обьектуудад ашиглагдана. Эдгээр batch action-ууд нь category модульд хэрэглэгдэхгүй, тиймээс, тэднийг устгацгаая:

# apps/backend/modules/category/config/generator.yml
config:
  list:
    batch_actions: {}

batch_actions боломж (option) –оор batch action-уудын жагсаалтыг тодорхойлдог. Хоосон array нь харагдахгүй болгоно.

Framework нь модуль бүрт default -аар delete batch action –ыг тодорхойлсон байдаг. Гэвч job модулийн хувьд сонгосон ажлуудыг дахин 30 –н өдрөөр сунгадаг байх хэрэгтэй учир extend үйлдэлийг нэмье:

# apps/backend/modules/job/config/generator.yml
config:
  list:
    batch_actions:
      _delete:    ~
      extend:     ~

Framework –оос хангаж өгдөг action-ууд нь бүгдээрээ _ (доогуур зураас) –аар эхэлдэг. Хэрэв броузероо (browser) refresh хийгээд batch action –аас extend –ийг сонговол, symfony “та executeBatchExtend() функцыг үүсгэ” гэсэн утгатай алдааг илгээх болно:

// apps/backend/modules/job/actions/actions.class.php
class jobActions extends autoJobActions
{
  public function executeBatchExtend(sfWebRequest $request)
  {
    $ids = $request->getParameter('ids');

    $q = Doctrine_Query::create()
      ->from('JobeetJob j')
      ->whereIn('j.id', $ids);

    foreach ($q->execute() as $job)
    {
      $job->extend(true);
    }

    $this->getUser()->setFlash('notice', 'The selected jobs have been extended successfully.');

    $this->redirect('jobeet_job');
  }
}

Сонгогдсон primary key –үүдийг ids параметрт хадгалдаг. Сонгогдсон ажил бүрийн хувьд дуусах хугацааг шалгахыг заасан нэмэлт аргументтай JobeetJob::extend() функцыг дууддаг.

Энэ шинэ аргументыг тавьж extend() функцыг сайжруулна:

// lib/model/doctrine/JobeetJob.class.php
class JobeetJob extends BaseJobeetJob
{
  public function extend($force = false)
  {
    if (!$force && !$this->expiresSoon())
    {
      return false;
    }

    $this->setExpiresAt(date('Y-m-d', time() + 86400 * sfConfig::get('app_active_days')));
    $this->save();

    return true;
  }

  // ...
}

Бүх ажил сунгагдсаны дараа хэрэглэгч рүү job модулийн нүүр хуудсыг дахин харуулах болно.

object_actions (обьектын үйлдлүүд)

Жагсаалтын actions гэсэн нэмэлт багананд тухайн нэг обьект дээр хийгдэх үйлдлүүд байдаг. Category модулийн хувьд категорийн нэрэнд нь засварлах холбоос холбогдсон ба жагсаалтаас шууд устгах холбоос ил байх нь бидэнд хэрэггүй тул засварлах болон устгах үйлдлүүдийг устгацгаая:

# apps/backend/modules/category/config/generator.yml
config:
  list:
    object_actions: {}

Харин job модуль дээр batch action дээр нэмсэнтэй адил extend үйлдлийг нэмж харуулая:

# apps/backend/modules/job/config/generator.yml
config:
  list:
    object_actions:
      extend:     ~
      _edit:      ~
      _delete:    ~

batch action –ны хувьд framework нь _delete болон _edit үйлдлүүдийн аль нэгийг нь тодорхойлдог. Бид extend холбоосын ажиллагааг хангах listExtend() үйлдлийг тодорхойлох хэрэгтэй:

// apps/backend/modules/job/actions/actions.class.php
class jobActions extends autoJobActions
{
  public function executeListExtend(sfWebRequest $request)
  {
    $job = $this->getRoute()->getObject();
    $job->extend(true);

    $this->getUser()->setFlash('notice', 'The selected jobs have been extended successfully.');

    $this->redirect('jobeet_job');
  }

  // ...
}

аctions (үйлдлүүд)

Бид сая нэг эсвэл олон (жагсаалт) обьект дээр хийгдэх холбоос үйлдийн тухай үзсэн билээ. Шинэ обьект үүсгэдэг холбоостой адилхан ямар нэг обьект дээр тавидаггүй үйлдлүүдийг actions боломж (option) –оор тодорхойлдог. default new үйлдлийг (action) устгаад нийтлэгчээр (ажил оруулагч) идэвхижүүлэлт хийгдэлгүй 60 –аас их өдөр болж байгаа бүх ажиллуудыг устгах шинэ үйлдэл (action)  нэмцгээе:

# apps/backend/modules/job/config/generator.yml
config:
  list:
    actions:
      deleteNeverActivated: { label: Delete never activated jobs }

Бид одоог хүртэл тодорхойлсон бүх үйлдлүүд (actions) –ээ ~ тэмдгээр тодорхойлсон. Энэ нь symfony үйлдлийг (action) автоматаар тохируулна гэсэн утгатай. Параметрын массив (array) тодорхойлсоноор үйлдлийг (action) өөрчилж болно. label боломж (option) нь symfony –н үүсгэсэн default label –г дарна.

Холбоос дээр дарахад default –аар үйлдлийн (action) нэрийн өмнө нь list гэсэн угтвар залгасан үйлдэл (action) ажиллах болно.

job модульд listDeleteNeverActivated үйлдлийг үүсгэе:

// apps/backend/modules/job/actions/actions.class.php
class jobActions extends autoJobActions
{
  public function executeListDeleteNeverActivated(sfWebRequest $request)
  {
    $nb = Doctrine_Core::getTable('JobeetJob')->cleanup(60);

    if ($nb)
    {
      $this->getUser()->setFlash('notice', sprintf('%d never activated jobs have been deleted successfully.', $nb));
    }
    else
    {
      $this->getUser()->setFlash('notice', 'No job to delete.');
    }

    $this->redirect('jobeet_job');
  }

  // ...
}

Бид өчигдөр тодорхойлсон JobeetJobTable::cleanup() функцыг дахин ашиглах болно. Дахин ашиглалтын өөр сайхан жишээ бол MVC загвар юм.

action параметрыг дамжуулсанаар гүйцэтгэх үйлдлийг өөрчилж болно:
deleteNeverActivated: { label: Delete never activated jobs, action: foo }

table_method (хүснэгтийн функц)

Ажлын (job) жагсаалтын хуудсыг харуулахад хэрэглэгдсэн өгөгдлийн сангийн (database) –ийн хүсэлтийн тоо нь 14 байгааг web debug toolbar  дээр үзүүлсэн байна.

Хэрэв та уг тоон дээр дарвал ажил (job) бүрийн хувьд категорийн нэрийг дахин авчирсан олон хүсэлт байгааг харах болно:

Query –ийн тоог цөөлөхийн тулд, бид table_method боломж (option) –ийг хэрэглэн ажил авч байгаа default функцыг сольж болно:

# apps/backend/modules/job/config/generator.yml
config:
  list:
    table_method: retrieveBackendJobList

retrieveBackendJobList() функцэнд job болон category хүснэгтүүдийг (tables) хооронд нь холбох холболт нэмсэнээр категори (category) обьект нь ажил (job) бүртэй автомат холболт үүсгэнэ.

Одоо lib/model/doctrine/JobeetJobTable.class.php. файлын JobeetJobTable –д retrieveBackendJobList функц үүсгэх хэрэгтэй.

// lib/model/doctrine/JobeetJobTable.class.php
class JobeetJobTable extends Doctrine_Table
{
  public function retrieveBackendJobList(Doctrine_Query $q)
  {
    $rootAlias = $q->getRootAlias();

    $q->leftJoin($rootAlias . '.JobeetCategory c');

    return $q;
  }

  // ...

retrieveBackendJobList() функцэнд job болон category хүснэгтүүдийг (tables) хооронд нь холбох холболт нэмсэнээр категори (category) обьект нь ажил (job) бүртэй автомат холболт үүсгэнэ.

Одоо хүсэлтийн тоо нь дөрөв болсон байна:

Form Views Configuration (формын харагдацын тохиргоо)

Формын харагдацын тохиргоо нь form, edit, болон new гурван хэсгээс бүтнэ. Эдгээрийн тохиргоонууд үйлчлэл нь ижилхэн бөгөөд зөвхөн form хэсгийн тохиргоог хийхэд edit болон new хэсэгүүдэд нөлөөлнө.

display (харагдац)

Жагсаалтын хувьд display боломж (option) –оор дэлгэцэнд харагдах талбаруудыг өөрчилж байсан. Харин формыг харуулахдаа талбарыг устгах гэж оролдох хэрэггүй бөгөөд устгавал санамсаргүй оролтын алдаанууд  (unexpected validation errors) үүсч болно.

Формын харагдацын display боломж (option) –г ашиглан талбаруудыг эмхлэж, групп үүсгэж болдог:

# apps/backend/modules/job/config/generator.yml
config:
  form:
    display:
      Content: [category_id, type, company, logo, url, position, location, description, how_to_apply, is_public, email]
      Admin:   [_generated_token, is_activated, expires_at]

Дээрхи тохиргоо нь Content болон Admin гэсэн хоёр групп үүсгэж, групп бүрт байх формын талбаруудыг тавьж өгсөн байна.

–  Admin групп дах баганууд нь одоохондоо броузер дээр харагдахгүй байгаа, учир нь тэднийг ажил (job) формын тодорхойлолтонд харуулахгүй (unset) гэж тодорхойлсон. Админ application –ны ажил (job) формын загварыг тодорхойлоход тэдгээр нь цөөхөн харагдана.

Admin generator нь олон – олон (n-n) гэсэн холбоог дэмждэг. Категори (category) формд, танд нэр (name) , slug оруулах input box болон affiliate (элсэх)- тэй холбоотой drop-down box байгаа. Энэ хуудсанд энэ холбоог (relation) засварлах боломж байх хэрэггүй. Тиймээс үүнийг устгая (харуулахгүй болгох):

// lib/form/doctrine/JobeetCategoryForm.class.php
class JobeetCategoryForm extends BaseJobeetCategoryForm
{
  public function configure()
  {
    unset($this['created_at'], $this['updated_at'], $this['jobeet_affiliates_list']);
  }
}

“Virtual&#8221; columns (хийсвэр баганууд)

Ажил (job) формын display боломж (options) –д  _generated_token талбар доогуур зураастай (_) –тай үүсдэг. Энэ нь энэ талбарыг үүсгэхэд _generated_token.php partial (хэсэгхэн) загвар ашиглана гэсэн утгатай юм.

Энэ partial –ыг дараах кодоор үүсгэнэ:

// apps/backend/modules/job/templates/_generated_token.php
<div>
  <label>Token</label>
  <?php echo $form->getObject()->getToken() ?>
</div>

Partial –д, та тухайн форм руу хандаж ба холбоотой обьектыг  getObject() функцээр  хялбархан авч болно.

v  Түүнчлэн компонентын үүсгэлтийг талбарын өмнө долгионтой зураас (~) тавьж төлөөлүүлж болно.

class (класс)

Администраторууд формыг хэрэглэдэг бөгөөд бид хэрэглэгчийн ажлын форм тодорхойлсоноос илүү их мэдээллийг дэлгэцэнд харна. Гэвч одоо тэдний заримыг нь JobeetJobForm классаас устгасан тул форм дээр харагдахгүй.

Frontend болон backend –ийн формууд нь өөр байх тул бид формын хоёр классыг үүсгэх хэрэгтэй. BackendJobeetJobForm классаас удамшсан JobeetJobForm классыг үүсгэе. Бидэнд hidden хийх (нуух) ижилхэн талбарууд байхгүй учир BackendJobeetJobForm –г дахин тодорхойлох JobeetJobForm классын функц дэх unset() зарлагааг бага зэрэг зөөж өөрчиллөх хэрэгтэй:

// lib/form/doctrine/JobeetJobForm.class.php
class JobeetJobForm extends BaseJobeetJobForm
{
  public function configure()
  {
    $this->removeFields();

    $this->validatorSchema['email'] = new sfValidatorAnd(array(
      $this->validatorSchema['email'],
      new sfValidatorEmail(),
    ));

    // ...
  }

  protected function removeFields()
  {
    unset(
      $this['created_at'], $this['updated_at'],
      $this['expires_at'], $this['is_activated'],
      $this['token']
    );
  }
}

// lib/form/doctrine/BackendJobeetJobForm.class.php
class BackendJobeetJobForm extends JobeetJobForm
{
  protected function removeFields()
  {
    unset(
      $this['created_at'], $this['updated_at'],
      $this['token']
    );
  }
}

Admin generator –ийн degfault  форм классыг class боломж (option) –оор тодорхойлдог:

# apps/backend/modules/job/config/generator.yml
config:
  form:
    class: BackendJobeetJobForm

v  Шинэ класс нэмсэний дараа кэйш устгахаа мартаж болохгүй.

The edit form still has a small annoyance. Тухайн upload хийгдсэн лого нь харагдахгүй байгаа бөгөөд түүнийг устгаж чадахгүй. sfWidgetFormInputFileEditable widget  нь засварлах боломжтой файл оруулах энгийн widget –ийг нэмдэг:

// lib/form/doctrine/BackendJobeetJobForm.class.php
class BackendJobeetJobForm extends JobeetJobForm
{
  public function configure()
  {
    parent::configure();

    $this->widgetSchema['logo'] = new sfWidgetFormInputFileEditable(array(
      'label'     => 'Company logo',
      'file_src'  => '/uploads/jobs/'.$this->getObject()->getLogo(),
      'is_image'  => true,
      'edit_mode' => !$this->isNew(),
      'template'  => '<div>%file%<br />%input%<br />%delete% %delete_label%</div>',
    ));

    $this->validatorSchema['logo_delete'] = new sfValidatorPass();
  }

  // ...
}

sfWidgetFormInputFileEditable widget  -н харагдалт болон онцлогыг тохируулах хэдэн сонголт (option) –ыг  тавьж өгнө:

  • file_src: тухайн upload хийгсэн файлын вэб зам (path)
  • is_image:  хэрэв үнэн бол файлыг зураг шиг харуулна (render)
  • edit_mode: форм нь засварлах горимд эсэх
  • with_delete: устгах checkbox –г харуулах эсэх
  • template: widget харуулах загвар хэрэглэх

Admin generator –ын харагдацаныг  үүсгэгдэх template (загвар)-т class болон id атрибутуудыг тодорхойлсоноор хялбархан тохируулж болно. Тухайлбал, sf_admin_form_field_logo классыг хэрэглэсэнээр лого талбарыг өөрчилж болно. Талбар бүрт түүнчлэн sf_admin_text эсвэл sf_admin_boolean гэх мэт талбарын төрлөөс хамаарсан класс байна.

edit_mode сонголт (option) нь sfDoctrineRecord::isNew()функцыг хэрэглэдэг.

Хэрэв формын model обьект нь шинэ бол үнэн бусад үед худал утга буцаадаг. Та embedded обьектын төлвөөс хамаарсан өөр widget эсвэл validator –уудыг хэрэглэхэд энэ нь сайн тусламж болно.

Filters Configuration (шүүлтийн тохиргоо)

Шүүлтийн тохиргоо хийх нь формын харагдацыг тохируулсантай яг адилхан. Учир нь шүүлт бол формын тухайн нэг тохиолдол юм. Формын классуудыг doctrine:build --all коммандаар үүсгэсэн. Мөн doctrine:build --filters коммандаар тэднийг дахин үүсгэж (re-generate) болно.

Шүүлт формын классууд нь lib/filter/ хавтсанд байрладаг ба model класс бүрийн форм класст туслах шүүлт класс байна. (JobeetJobForm классын хувьд JobeetJobFormFilter класс).

Категори (categоry ) модулийн хувьд тэднийг бүрт устгая:

# apps/backend/modules/category/config/generator.yml
config:
  filter:
    class: false

Ажил ( job ) модулийн хувьд заримыг нь усгая:

# apps/backend/modules/job/config/generator.yml
filter:
  display: [category_id, company, position, description, is_activated, is_public, email, expires_at]

Шүүлт нь үргэлж туслах чанарын байдаг тул шүүлт формын классыг дахин тодорхойлогүйгээр харагдах талбаруудыг тохируулдаг.

Actions Customization (үйлдлүүдийн өөрчлөлт)

Тохиргоо хангалтгүй үед action класст шинэ функц нэмнэ. Бид өмнө нь extend онцлогыг нэмж байсан. Мөн үүсгэгдсэн action функцуудыг дахин тодорхойлж болно:

Функц Тайлбар
executeIndex() Жагсаалт харагдацын action
executeFilter() Шүүлтүүдыг шинэчилнэ
executeNew() New (шинээр үүсгэх) харагдацын action
executeCreate() Шинэ ажил (Job) үүсгэнэ
executeEdit() Edit (засварлах) харагдацын action
executeUpdate() Ажил (Job) шинэчилнэ
executeDelete() Ажил (Job) устгана
executeBatch() batch action биелүүлнэ
executeBatchDelete() _delete batch action –г биелүүлнэ
processForm() Ажил форм (Job form) боловсруулах
getFilters() Тухайн шүүлтүүдийг буцаана
setFilters() Шүүлт тавина
getPager() Жагсаалт (list) pager буцаана
getPage() Хуудаслагчийн хуудасыг (paper page) авна
setPage() Хуудаслагчийн хуудасыг (paper page) тавина
buildCriteria() Жагсаалтын (list) Criteria байгуулна
addSortCriteria() Жагсаалтын эрэмбэлсэн Criteria нэмнэ
getSort() Тухайн эрэмбэлсэн баганыг буцаана
setSort() Тухайн эрэмбэлэх баганыг тавина

Үүсгэгдсэн функц бүр зөвхөн нэг зүйлтэй, энэ нь олон код copy болон paste хийхгүйгээр байдлыг (behavior) өөрчлөхөд хялбар юм.

Templates Customization (загварын өөрчлөлт)

Бид admin generator нь HTML кодонд class болон id аттрибутуудыг нэмж үүсгэсэн template (загвар) –г хэрхэн өөрчилдгийг харлаа.

Мөн та классуудад оргинал template (загвар) –уудыг дахин тодорхойлж болно. Template (загвар)  -ууд нь энгийн PHP файлууд болон PHP биш классууд юм. Модуль ижил нэртэй template (загвар)  үүгэсэнээр template (загвар) –г дахин тодорхойлж болно (тухайлбал job админ модулийн apps/backend/modules/job/templates/ хавтсанд):

Template (загвар) Тайлбар
_assets.php Темплатиүдэд хэрэглэгдэх CSS болон JS харуулна
_filters.php filters box (шүүлт) –г харуулна
_filters_field.php filter (шүүлт) –н нэг field (талбар) –г үзүүлнэ
_flashes.php flash мессежүүдийг үзүүлнэ
_form.php Формыг харуулна
_form_actions.php Формын action –уудыг харуулна
_form_field.php Формын нэг field (талбар) –г харуулна
_form_fieldset.php Формын fieldset -г харуулна
_form_footer.php Формын footer –г харуулна
_form_header.php Формын header –г харуулна
_list.php Жагсаалт (list)-ыг харуулна
_list_actions.php Жагсаалтын action –уудыг харуулна
_list_batch_actions.php Жагсаалтын batch action-уудыг харуулна
_list_field_boolean.php Жагсаалтын нэг boolean талбар (field) –г харуулна
_list_footer.php Жагсаалтын footer –г харуулна
_list_header.php Жагсаалтын header –г харуулна
_list_td_actions.php Мөрийн (row) обьект action –уудыг харуулна
_list_td_batch_actions.php Мөрийн checkbox –г харуулна
_list_td_stacked.php Мөрийн stacked layout (давхарга) –г харуулна
_list_td_tabular.php Жагсаалтын нэг талбарыг (field) харуулна
_list_th_stacked.php header  -н нэг баганийн нэрийг харуулна
_list_th_tabular.php header  -н нэг баганийн нэрийг харуулна
_pagination.php Жагсаалтын хуудаслалтыг харуулна
editSuccess.php edit харагдац (view) –г харуулна
indexSuccess.php Жагсаалтын (list) харагдацыг харуулна
newSuccess.php new харагдацыг харуулна

Final Configuration (эцсийн тохиргоо)

Jobeet админ тохиргоо нь эцсийн байдлаар дараах шиг байна:

# apps/backend/modules/job/config/generator.yml
generator:
  class: sfDoctrineGenerator
  param:
    model_class:           JobeetJob
    theme:                 admin
    non_verbose_templates: true
    with_show:             false
    singular:              ~
    plural:                ~
    route_prefix:          jobeet_job
    with_doctrine_route:   true

    config:
      actions: ~
      fields:
        is_activated: { label: Activated?, help: Whether the user has activated the job, or not }
        is_public:    { label: Public? }
      list:
        title:         Job Management
        layout:        stacked
        display:       [company, position, location, url, is_activated, email]
        params:  |
          %%is_activated%% <small>%%JobeetCategory%%</small> - %%company%%
           (<em>%%email%%</em>) is looking for a %%=position%% (%%location%%)
        max_per_page:  10
        sort:          [expires_at, desc]
        batch_actions:
          _delete:    ~
          extend:     ~
        object_actions:
          extend:     ~
          _edit:      ~
          _delete:    ~
        actions:
          deleteNeverActivated: { label: Delete never activated jobs }
        table_method: retrieveBackendJobList
      filter:
        display: [category_id, company, position, description, is_activated, is_public, email, expires_at]
      form:
        class:     BackendJobeetJobForm
        display:
          Content: [category_id, type, company, logo, url, position, location, description, how_to_apply, is_public, email]
          Admin:   [_generated_token, is_activated, expires_at]
      edit:
        title: Editing Job "%%company%% is looking for a %%position%%"
      new:
        title: Job Creation

# apps/backend/modules/category/config/generator.yml
generator:
  class: sfDoctrineGenerator
  param:
    model_class:           JobeetCategory
    theme:                 admin
    non_verbose_templates: true
    with_show:             false
    singular:              ~
    plural:                ~
    route_prefix:          jobeet_category
    with_doctrine_route:   true

    config:
      actions: ~
      fields:  ~
      list:
        title:   Category Management
        display: [=name, slug]
        batch_actions: {}
        object_actions: {}
      filter:
        class: false
      form:
        actions:
          _delete: ~
          _list:   ~
          _save:   ~
      edit:
        title: Editing Category "%%name%%"
      new:
        title: New Category

Бид энэ хоёр тохиргооны файлуудад цаг хугацаа зарцуулсан хүчинд агуу backend интерфэйсийг хөгжүүллээ.

v  Та YAML файл дах зарим нэг тохируулгийг хялбар PHP код хэрэглэн хийх боломжтой гэдгийг мэдэж авсан байх. Admin generator –ийн хувьд, та apps/backend/modules/job/lib/jobGeneratorConfiguration.class.php файлыг засварлаж болно. Энэ нь  танд PHP интерфэйс дээр YAML файлынх шиг ижил боломжийг олгодог. Функцүүдийн нэрийг cache/backend/dev/modules/autoJob/lib/BaseJobGeneratorConfiguration.class.php. – д үүсгэгдсэн base классаас харж болно.

Final Thoughts (дүгнэлт)

Бид нэгхэн цагийн дотор Jobeet  прожектын бүрэн гүйцэт backend интерфэйсийг байгууллаа. Бүх хэсэгт нийлээд 50 хүрэхгүй PHP кодын мөр бичсэн билээ. Иймд олон онцлогууд нь тийм ч муу биш юм!

Маргааш бид backend application –ийг хэрэглэгчийн нэр болон нууц үгээр хамгаалах тухай үзнэ. Энэ нь түүнчлэн symfony –ын user классын талаар ярих шалтгаан болно.

Татаж авах холбоос:

http://hotfile.com/dl/77526893/3ed25d0/Symfony_Day12.doc.html

Advertisements

10 thoughts on “Practical symfony Day 12: The Admin Generator Орчуулсан Б.Батжаргал

  1. Сайн байна уу? Уул эхнээс нь үзээд явж байсан чинь 9, 10, 11 нь яаасан юм болоо 🙂

    • хэхэ. Харин нэг тиймэрхүү юм болчлоо. Орчуулж байгаа хүмүүс маань дэс дараалал хамаарахгүй сэдэв авч байгаа болохоор тэгэж байгаа байх.
      Гэхдээ минийхаар бол чухал сэдвүүд нь:
      Day 10: The Forms
      Day 12: The Admin Generator
      Day 13: The User
      Day 14: Feeds //нээх чухал биш
      Day 15: Web Services //нээх чухал биш
      Day 16: The Mailer //нээх чухал биш
      Day 17: Search
      Day 18: AJAX
      Day 19: Internationalization and Localization
      Day 20: The Plugins
      Day 21: The Cache

      ингэж л байгаа болов уу, тэгэхээр ямар нэг дараалал алдаагүй ээ зүгээр.
      Амжилт хүсье

  2. Сайн уу асуух юм байна

    би sfWidgetFormDateTime ыг UNSET хийсэн юм тэгээд админаас
    SAVE хийхэд автоматаар date() аваад явуулах гэсэн юм аа

    үүнтэй бас адил SESSION оос ямар нэг String аваад database руу
    бичих гэсийн SAVE үйлдэл хийхэд admin generate хийсэн

    та бүхэнд дахин баярлалаа

    • Сайн уу, Ингэж болно. Form-доо unset($this[‘your date field’]) гээд тухайн автоматаар хадгалагдах объектодоо setDate() gej method-г нь override хийж болно. Эсвэл process form дээрээ юмуу үндсэн классынхаа save method дээр бас override хийж болно. Жишээлбэл чи News gesen Model үүсгэсэн гэж бодвол
      li/model/doctrine/News.php -д
      public function save(Doctrine_Connection $conn = null){
      $this->_set(‘date’, date(‘Y-m-d));
      return parent::save($conn);
      }
      гэж болно, Session -ын утгыг бол processForm -deeree field-ee $news->setDate($this->getUser()->getAttribute(‘blahblah’)); гэх маягаар болно.
      гэх мэт өөрийн хүссэнээрээ хадгалж болно.

  3. ӨӨ нээрээ маш их баярлалаа та бүхэн маш их тус болж байгаа шүү
    дахин баярлалаа

  4. uneheer ih bayrlalaa. nadad iim neg aldaa garaad bn aa.help me !!!!!

    Parse error: parse error, expecting `’)&#8221; in C:\development\sfprojects\jobeet\cache\backend\dev\modules\a utoCategory\lib\BaseCategoryGeneratorConfiguration.class.php on line 101

Хариулт үлдээх

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Өөрчлөх )

Twitter picture

You are commenting using your Twitter account. Log Out / Өөрчлөх )

Facebook photo

You are commenting using your Facebook account. Log Out / Өөрчлөх )

Google+ photo

You are commenting using your Google+ account. Log Out / Өөрчлөх )

Connecting to %s