Practical symfony 11 дэх өдөр: Формын сорилт

Орчуулсан Ш.Ганбат
(combat_mn@yahoo.com)

Practical symfony 11 дэх өдөр: Формын сорилт

Өчигдөр бид Symfony ашиглан өөрсдийн анхны формыг байгуулсан. Одоо хэрэглэгч өөрийн шинэ ажлын байрыг Jobeet-од тавих боломжтой болсон тул бид зарим нэг сорилтыг амжиж нэмэх шаардлагатай.

Энэ бол бидний өнөөдрийн хийх ажил. Ингэх явцдаа бид формын фреймворкийг гүнзгийрүүлэн судлах болно.

Формын фреймворкийг Symfony-гүй дангаар нь ашиглах

Symfony-н бүрэлдэхүүнүүд нь маш уян хатнаар холбогддог. Өөрөөр хэлбэл тэдний олонхи нь MVC фреймворкоос тусдаа ашиглагдах боломжтой гэсэн үг. Формын фреймворк ч мөн адил Symfony-с хамааралгүй. Та түүнийг дурын PHP апликейшнд lib/form/, lib/widgets/ ба lib/validators/ директориудыг холбож өгөн ашиглах боломжтой.

Дангаар нь ашиглах боломжтой Symfony-н өөр нэг бүрэлдэхүүн бол route фреймворк юм. lib/routing/ директорийг өөрийн төсөлдөө хуулж хийгээд та URL-ээрээ гангараарай.

Хамааралгүй бүрэлдэхүүнүүд нь symfony platform-ыг бүрдүүлдэг:

Формыг илгээх (Submitting a Form)

Ажлын байр үүсгэх болон баталгаажуулах процесст функциональ сорилтуудыг нэмэх зорилгоор jobActionsTest файлыг нээцгээе.

Ажлын байр үүсгэх хуудсыг харахын тулд та файлын төгсгөлд  дараах кодыг нэм:

// test/functional/frontend/jobActionsTest.php

$browser->info('3 - Post a Job page')->

info('  3.1 - Submit a Job')->

get('/job/new')->

with('request')->begin()->

isParameter('module', 'job')->

isParameter('action', 'new')->

end();

Бид өмнө нь click() методыг линкийн симуляцид ашиглаж байсан. Формыг илгээхэд яг тийм аргыг хэрэглэж болно. Формын хувьд та талбар бүрийн утгыг методын хоёрдогч аргументаар илгээх боломжтой.  Браузер объект нь жинхэнэ браузерийн нэгэн адилаар формын илгээгдсэн утгуудыг дефаолт утгуудтай нь нэгтгэдэг.

Харин талбарын утгуудыг дамжуулахын тулд та тэдгээрийн нэрийг мэдэж байх хэрэгтэй. Хэрэв та хуудасны эх кодыг нээх юмуу Firefox Web Developer Toolbar-ын тусламжтайгаар “Forms > Display Form Details”-ийг харвал company талбарын нэр нь үнэн чанартаа jobeet_job[company] болохыг олж харна.

PHP нь jobeet_job[company] гэсэнтэй ижил хэлбэрийн нэрүүдрийг автоматаар jobeet_job нэртэй массив болгон хувиргадаг.

Формын талбаруудын нэрсийг илүү тодорхой болгохын тулд job[%s] форматыг оруулах дараах кодыг JobeetJobForm классын configure() методын төгсгөлд бичье.

// lib/form/doctrine/JobeetJobForm.class.php

$this->widgetSchema->setNameFormat('job[%s]');

Энэ өөрчлөлтийн дараа company талбарын нэр нь таны браузерт job[company] гэсэн хэрлбэртэйгээр харагдана. Тэгэхээр одоо талбаруудын шалгагдсан утгуудыг формд дамжуулахын тулд "Preview your job" товчлуурыг дарах цаг нь болсон:

// test/functional/frontend/jobActionsTest.php

$browser->info('3 - Post a Job page')->

info('  3.1 - Submit a Job')->

get('/job/new')->

with('request')->begin()->

isParameter('module', 'job')->

isParameter('action', 'new')->

end()->

click('Preview your job', array('job' => array(

'company'      => 'Sensio Labs',

'url'          => 'http://www.sensio.com/',

'logo'         => sfConfig::get('sf_upload_dir').'/jobs/sensio-labs.gif',

'position'     => 'Developer',

'location'     => 'Atlanta, USA',

'description'  => 'You will work with symfony to develop websites for our customers.',

'how_to_apply' => 'Send me an email',

'email'        => 'for.a.job@example.com',

'is_public'    => false,

)))->

with('request')->begin()->

isParameter('module', 'job')->

isParameter('action', 'create')->

end();

Хэрэв та файлын абсолют замыг зааж өгвөл браузерийн цонх нь файлын upload хийгдэж буй байдлыг дууриаж (симуляци) харуулна. Формыг илгээсний дараа create үйлдэл гүйцэтгэгдсэн эсэхийг бид шалгасан.

Формын тестер (form tester)

Бидний илгээсэн форм хүчинтэй байх ёстой. Та үүнийн формын тестер ашиглан шалгаж болно:

with('form')->begin()->

hasErrors(false)->

end()->

Формын тестер нь формын одоогийн статусыг шалгах хэд хэдэн методтой, ж.нь errors.

Хэрэв та сорилтдоо алдаа гаргасан бол сорилт ажиллахгүй. Энэ тохиолдолд та 9 дэх өдрийн хичээлээр үзсэн with(‘response’)->debug()statement-ийг ашиглаж болно. Гэхдээ та алдааны мессежийг олж харахын тулд үүссэн HTML кодыг ухахаас өөр аргагүй. Энэ нь үнэхээр тохиромжгүй тул формын тестер нь формын статус болон түүнтэй холбоотой бүх алдааны мэдээллийг харуулдаг debug() методыг санал болгодог.

with(‘form’)->debug()

Redirect-ийн сорилт

Форм маань баталгаажиж, шинээр ажлын байр үүссэн тул одоо redirect хийгдэж хэрэглэгч show хуудас руу шилжинэ.

isRedirected()->

followRedirect()->

with('request')->begin()->

isParameter('module', 'job')->

isParameter('action', 'show')->

end()->

isRedirected() метод нь redirect хийгдсэн эсэхийг шалгадаг, харин followRedirect() метод нь redirect-ийн гүйцэтгэлийг хангадаг.

Танд redirect хийгдэхийн өмнө объектуудын байдлыг шалгах шаардлага гарч болзошгүй учраас sfBrowser класс нь автоматаар redirect хийдэггүй.

Доктриний тестер

Хэрэглэгч ажлын байраа хараахан нийтлээгүй байгаа болохоор эцсийн дүнд бид ажлын байрны мэдээлэл баазад хадгалагдсан эсэх болон activated талбарын утга false байгаа эсэхэд сорилт хийх болж байна.

Үүнийг бид өнөөг хүртэл огт хэрэглээгүй байгаа Доктриний тестерийн тусламжтайгаар хялбархан гүйцэтгэж болно. Доктриний тестер нь суугаагүй байдаг тул эхлээд түүнийг нэмцгээе:

$browser->setTester(‘doctrine’, ‘sfTesterDoctrine’);

Доктриний тестер нь өгөгдлийн бааз дахь нэг эсвэл хэд хэдэн объект аргументад өгөгдсөн шалгуурт нийцэж буй эсэхийг шалгах check() методыг санал болгодог.

with('doctrine')->begin()->

check('JobeetJob', array(

'location'     => 'Atlanta, USA',

'is_activated' => false,

'is_public'    => false,

))->

end()

Шалгуурууд нь дээрхи жишээн дээр үзсэнтэй адил утгуудын массив, эсвэл илүү нарийн хүсэлтүүдийн хувьд Doctrine_Query-ийн instance байж болно. Та шалгуурыг хангаж буй объект байгаа эсэхийг гуравдагч аргуметыг Boolean (дефаолт нь true)-аар өгөх, эсвэл Integer-ээр  өгөөд тохирч буй объектын тоог гаргах замаар тогтоох боломжтой.

Алдаагаар сорилт хийх

Хэрэв бид зөв утгуудыг илгээвэл ажлын байрны форм нь бидний хүлээж байснаар үүснэ. Харин буруу утга илгээхийг оролдсон тохиолдолд ямар үр дүн гарахыг шалгах зорилгоор дараах сорилтыг нэмье.

$browser->

info('  3.2 - Submit a Job with invalid values')->

get('/job/new')->

click('Preview your job', array('job' => array(

'company'      => 'Sensio Labs',

'position'     => 'Developer',

'location'     => 'Atlanta, USA',

'email'        => 'not.an.email',

)))->

with('form')->begin()->

hasErrors(3)->

isError('description', 'required')->

isError('how_to_apply', 'required')->

isError('email', 'invalid')->

end();

hasErrors() метод нь бүхэл тоон аргумент өгөгдсөн нөхцөлд алдааны тоог, isError() метод нь тухайн талбарын кодын алдааг тус тус туршина.

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

Түүнчлэн та алдааны мэдээлэл агуулж буй эсэхийг нь шалгах зорилгоор үүссэн HTML-ийг туршиж болох хэдий ч бид формын давхаргыг (layout) өөрчлөөгүй байгаа тул манай тохиолдолд энэ нь зайлшгүй хийх зүйл биш.

Одоо бүгдээрээ урьдчилан харах цонхны админ-баарыг туршъя. Одоохондоо ажлын байрууд идэвхжээгүй байгаа учраас та түүнийг засварлах, устгах эсвэл нийтлэх боломжтой. Энэ гурван линкийг туршихын тулд эхлээд бид ажлын байрыг үүсгэх хэрэгтэй. Гэтэл баахан copy – paste хийх шаардлагатай, бид харин үүнд дургүй тул JobeetTestFunctional классд ажлын байр үүсгэх методыг нэмж оруулъя:

// lib/test/JobeetTestFunctional.class.php

class JobeetTestFunctional extends sfTestFunctional

{

public function createJob($values = array())

{

return $this->

get('/job/new')->

click('Preview your job', array('job' => array_merge(array(

'company'      => 'Sensio Labs',

'url'          => 'http://www.sensio.com/',

'position'     => 'Developer',

'location'     => 'Atlanta, USA',

'description'  => 'You will work with symfony to develop websites for our customers.',

'how_to_apply' => 'Send me an email',

'email'        => 'for.a.job@example.com',

'is_public'    => false,

), $values)))->

followRedirect()

;

}

// ...

}

createJob() метод нь ажлын байрыг үүсгэн, redirect хийж, урсагч интерфейсийг (fluent interface) тасалдуулахгүй байх үүднээс браузерийг буцаадаг. Түүнчлэн та зарим дефаолт утгуудтай нэгдэх утгуудын массивыг дамжуулж болно.

Линкийн HTTP методыг албадах (Forcing the HTTP Method of a link)

“Publish” линкийг турших нь одоо харьцангуй хялбар болсон:

$browser->info('  3.3 - On the preview page, you can publish the job')->

createJob(array('position' => 'FOO1'))->

click('Publish', array(), array('method' => 'put', '_with_csrf' => true))->

with('doctrine')->begin()->

check('JobeetJob', array(

'position'     => 'FOO1',

'is_activated' => true,

))->

end();

10 дахь өдрийн хичээлээс та санаж байгаа бол, “Publish” линк нь HTTP PUT методоор дуудагдахаар тохируулагдсан. Браузерууд PUT хүсэлтийг ойлгохгүй тул link_to() хэлпер нь линкийн зарим кодыг JavaScript-рүү хөрвүүлдэг.  Харин сорилтын браузерт JavaScript ажиллахгүй учраас click() методын гуравдагч option-оор PUT методыг албадан дамжуулах шаардлагатай болдог. Түүнээс гадна, бид хичээлийн эхний өдөр CSRF хамгаалалтыг зөвшөөрсөн болохоор link_to() хэлпер нь CSRF токенийг оруулж, _with_csrf option нь энэхүү токенийг дууриадаг (симуляци).

“Delete” линкийн сорилт нь дээрхтэй яг адил:

$browser->info('  3.4 - On the preview page, you can delete the job')->

createJob(array('position' => 'FOO2'))->

click('Delete', array(), array('method' => 'delete', '_with_csrf' => true))->

with('doctrine')->begin()->

check('JobeetJob', array(

'position' => 'FOO2',

), false)->

end();

Сорилтууд аюулаас хамгаална

Ажлын байр нийтлэгдсэн бол та түүнийг дахин засварлах боломжгүй. Хэдийгээр “Edit” линк урьдчилан харах цонхонд харагдахаа больсон ч, дээрхи шаардлагыг хангаж буй эсэхийг шалгах зорилгоор хэдэн сорилт нэмцгээе.

Эхлээд createJob() методод ажлын байрыг автоматаар нийтлэгдэхийг зөвшөөрөх шинэ аргумент нэмж, тухайн ажлын байрны байрлалын утгыг буцаадаг getJobByPosition() методыг үүсгэе:

// lib/test/JobeetTestFunctional.class.php

class JobeetTestFunctional extends sfTestFunctional

{

public function createJob($values = array(), $publish = false)

{

$this->

get('/job/new')->

click('Preview your job', array('job' => array_merge(array(

'company'      => 'Sensio Labs',

'url'          => 'http://www.sensio.com/',

'position'     => 'Developer',

'location'     => 'Atlanta, USA',

'description'  => 'You will work with symfony to develop websites for our customers.',

'how_to_apply' => 'Send me an email',

'email'        => 'for.a.job@example.com',

'is_public'    => false,

), $values)))->

followRedirect()

;

if ($publish)

{

$this->

click('Publish', array(), array('method' => 'put', '_with_csrf' => true))->

followRedirect()

;

}

return $this;

}

public function getJobByPosition($position)

{

$q = Doctrine_Query::create()

->from('JobeetJob j')

->where('j.position = ?', $position);

return $q->fetchOne();

}

// ...

}

Ажлын байр нийтлэгдсэн бол засварлах хуудас нь 404 status code-ийг буцаах ёстой.

$browser->info('  3.5 - When a job is published, it cannot be edited anymore')->

createJob(array('position' => 'FOO3'), true)->

get(sprintf('/job/%s/edit', $browser->getJobByPosition('FOO3')->getToken()))->

with('response')->begin()->

isStatusCode(404)->

end();

Харин бид өчигдөр хамгаалалтыг бүрэн хэмжээгээр хэрэгжүүлэхээ мартсан тул та сорилтоос хүссэн үр дүнгээ харж чадахгүй. Та бүхий л муу зүйлийг урьдчилан тооцсон байх ёстой учраас сорилт бичих нь кодын цоорхойг илрүүлэх хамгийн зөв арга юм.

Цоорхойг нөхөх нь маш амархан, учир нь ажлын байр идэвхжсэн нөхцөлд бид хэрэглэгчийг зүгээр л 404 status code-ын хуудас руу дамжуулчихаж болно.

// apps/frontend/modules/job/actions/actions.class.php

public function executeEdit(sfWebRequest $request)

{

$job = $this->getRoute()->getObject();

$this->forward404If($job->getIsActivated());

$this->form = new JobeetJobForm($job);

}

Алдааг засах нь маш хялбар байлаа. Гэхдээ та бусад бүх зүйл хүссэний дагуу ажиллана гэдэгт итгэлтэй байна уу? Та өөрийн браузерийг нээж ажлын байр засварлах хуудасд нэвтрэх боломжит бүх хувилбар комбинациудаар сорилт хийж үзэж болно. Гэхдээ үүнээс дээр арга бий: өөрийн сорилтуудын цуглуулгыг ажиллуулж үзэх; хэрэв та регресс оруулбал Symfony нэн даруй танд мэдээлнэ.

Сорилтын ирээдүй рүү буц

Ажлын байрны хугацаа дуусахаас 5-аас цөөн хоног үлдсэн, эсвэл хугацаа нь аль хэдийн дууссан бол хэрэглэгч энэхүү хугацааг өнөөдрөөс эхлэн дахин 30 хоногоор сунгаж болно.

Энэ шаардлагыг браузерт турших нь хялбар биш даалгавар, учир нь хүчинтэй хугацаа нь ажлын байрыг үүсгэхэд автоматаар 30 хоногоор тавигддаг. Ийм учраас ажлын байрны хуудсыг нээхэд хугацаа сунгах линк байдаггүй. Мэдээж хэрэг та огноог баазад нь шууд өөрчлөх, эсвэл хуудасны темплэйтийг өөрчилж линкийг байнга харагдаж байхаар болгон засварлаж болно. Гэв ч энэ нь ядаргаатай бөгөөд асар олон алдааг дагуулна.

Таны таамагласанчлан, цөөн хэдэн сорилт бичих нь бидэн дахин тус болно.

Байнга хийдэг шигээ бид эхний ээлжинд extend методод шинэ route нэмж өгөх шаардлагатай:

# apps/frontend/config/routing.yml

job:

class:   sfDoctrineRouteCollection

options:

model:          JobeetJob

column:         token

object_actions: { publish: PUT, extend: PUT }

requirements:

token: \w+

Дараа нь _admin partial дахь “Extend” линкийн кодыг баяжуулъя:

<!-- apps/frontend/modules/job/templates/_admin.php -->

<?php if ($job->expiresSoon()): ?>

- <?php echo link_to('Extend', 'job_extend', $job, array('method' => 'put')) ?> for another <?php echo sfConfig::get('app_active_days') ?> days

<?php endif; ?>

Контроллерт extend  үйлдлийг үүсгэе:

// apps/frontend/modules/job/actions/actions.class.php

public function executeExtend(sfWebRequest $request)

{

$request->checkCSRFProtection();

$job = $this->getRoute()->getObject();

$this->forward404Unless($job->extend());

$this->getUser()->setFlash('notice', sprintf('Your job validity has been extended until %s.', $job->getDateTimeObject('expires_at')->format('m/d/Y')));

$this->redirect('job_show_user', $job);

}

Контроллер нь JobeetJob классын extend() метод ажлын байрны хугацаа сунгагдсан бол true, үгүй бол false утгыг буцаана гэж хүлээж байгаа:

// lib/model/doctrine/JobeetJob.class.php

class JobeetJob extends BaseJobeetJob

{

public function extend()

{

if (!$this->expiresSoon())

{

return false;

}

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

$this->save();

return true;

}

// ...

}

Эцэст нь сорилтын сценарийг нэмье:

$browser->info('  3.6 - A job validity cannot be extended before the job expires soon')->

createJob(array('position' => 'FOO4'), true)->

call(sprintf('/job/%s/extend', $browser->getJobByPosition('FOO4')->getToken()), 'put', array('_with_csrf' => true))->

with('response')->begin()->

isStatusCode(404)->

end()

;

$browser->info('  3.7 - A job validity can be extended when the job expires soon')->

createJob(array('position' => 'FOO5'), true);

$job = $browser->getJobByPosition('FOO5');

$job->setExpiresAt(date('Y-m-d'));

$job->save();

$browser->

call(sprintf('/job/%s/extend', $job->getToken()), 'put', array('_with_csrf' => true))->

with('response')->isRedirected();

$job->refresh();

$browser->test()->is(

$job->getDateTimeObject('expires_at')->format('y/m/d'),

date('y/m/d', time() + 86400 * sfConfig::get('app_active_days'))

);

Сорилтын сценарит хэд хэдэн шинэ зүйл бий:

  • call() метод нь URL-ээс GET юмуу POST-оос ялгаатай методуудыг ялган авч хүсэлт боловсруулан хэрэгжүүлдэг
  • Ажлын байрны мэдээлэл шинэчлэгдсэний дараа бидэнд $job->refresh()-ийн тусламжтайгаар локал объектыг дахин ачаалах шаардлага гардаг
  • Эцэст нь бид ажлын байрны хүчинтэй хугацааны сорилтыг шууд хийх боломжтой болох ба ингэхдээ оруулж өгсөн lime объектоо ашиглана

Формын аюулгүй байдал

Формын серилэлтийн ид шид (Form Serialization Magic!)

Формын Doctrine нь маш олон ажлыг автоматжуулсан тул хэрэглэхэд маш амар. Жишээлбэл формуудыг серилж баазад хадгалах үйлдлийг зүгээр л $form->save() гээд л боллоо.

Харин энэ бүхэн яаж ажилладаг юм бол? Нэн түрүүнд save()метод дараах алхмуудыг гүйцэтгэнэ:

  • Транзэкшнийг эхлүүлдэг (формын Doctrine нь бүгд үндсэн формтойгоо нэг дор хадгалагддаг учраас)
  • Илгээгдэсэн утгуудыг боловсруулдаг (хэрэв updateCOLUMNColumn() метод өгөгдсөн бол түүнийг дууддаг)
  • Багануудын утгыг шинэчлэх зорилгоор Doctrine объектийн fromArray() методыг дууддаг
  • Объектыг өгөгдлийн баазад хадгалдаг
  • Транзэкшнийг байгуулдаг (commit the transaction)

Аюулгүй байдлын мөн чанар (Built-in Security Features)

fromArray() метод нь утгуудын массивыг авч харгалзах багануудын утгыг шинэчилдэг. Энэ нь аюулгүй байдалд нөлөөлж чадах уу? Хэрэв хэн нэг нь өөрийн хандах эрхгүй баганын утгыг шинэчлэхийг оролдвол яах вэ? Жишээлбэл би token баганын утгыг хүчээр өөрчилж чадах уу?

Тэгвэл ажлын байрны мэдээллийг token талбартай хамтад нь хадгалж буй байдлыг дууриан харуулах (simulate) сорилт бичцэгээе:

// test/functional/frontend/jobActionsTest.php

$browser->

get('/job/new')->

click('Preview your job', array('job' => array(

'token' => 'fake_token',

)))->

with('form')->begin()->

hasErrors(7)->

hasGlobalError('extra_fields')->

end();

Та формыг илгээмэгцээ extra_fields гэсэн глобал алдаа гарахыг харах болно. Яагаад гэвэл дефаолтдаа форм нь нэмэлт талбар илгээхийг зөвшөөрдөггүй. Ийм ч учраас формын талбар бүр нь өөрийн валтдэйтортой байдаг.

Түүнчлэн та Firefox Web Developer Toolbar гэх мэт хэрэгсэл ашиглан браузерийн тусламжтайгаар нэмэлт талбар илгээхээр оролдож болно.

Та аюулгүй байдлын энэхүү арга хэмжээг allow_extra_fields сонголтын утгыг true болгох замаар идэвхгүй болгож болно.

class MyForm extends sfForm

{

public function configure()

{

// ...

$this->validatorSchema->setOption('allow_extra_fields', true);

}
}

Энэ тохиолдолд сорилт ажиллана, харин token талбарын утга илгээгдэхгүй орхигдоно. Ийм маягаар та өмнөхтэйгөө адил формын аюлгүй байдлыг алдагдуулж чадахгүй. Харин танд дээрхи сонголт үнэхээр хэрэтэй байгаа бол filter_extra_fields сонголтыг false болгоорой:

$this->validatorSchema->setOption(‘filter_extra_fields’, false);

Энэ бүлэгт бичсэн сорилтууд нь зөвхөн үзүүлэнгийн зориулалттай. Танд Symfony-н өөрийнх нь боломжийг сорих шаардлага байхгүй тул дээрхи сорилтуудыг Jobeet төслөөс устгаж болно.

XSS ба CSRF-ийн хамгаалалт

Эхний өдрийн хичээлээс л бид generate:app таск нь хамгаалагдсан апликейшн үүсгэдэг гэдгийг мэдэж авсан.

Юуны өмнө тэр XSS халдлагын эсрэг хамгаалалтыг идэвхжүүлдэг. Өөрөөр хэлбэл темплэйтэд хэрэглэгдэж буй бүх хувьсагчдад escape хийгдэхээр тохируулсан гэсэн үг. Хэрэв та дотроо HTML тэг агуулсан ажлын байрны мэдээлэл илгээвэл symfony түүнийг ердийн текст хэлбэрээр дэлгэцэд харуулна.

Түүнчлэн CSRF халдлагын эсрэг хамгаалалт мөн идэвхждэг. CSRF токен тавигдсан үед бүх формуудад  _csrf_token нууц талбар нэмэгддэг.

Escape-ийн стратеги болон CSRF нууцлалыг хүссэн цагтаа apps/frontend/config/settings.yml тохиргооны файлыг засварлан өөрчилж болно. Түүнчлэн databases.yml файлд гүйцэтгэлийн тодорхой орчинд зориулсан тохиргоонууд агуулагддаг.

all:

.settings:

# Form security secret (CSRF protection)

csrf_secret: Unique$ecret

# Output escaping settings

escaping_strategy: true

escaping_method:   ESC_SPECIALCHARS

Хэрэглээний таск үүсгэх

Symfony нь хэдийгээр вэб фреймворк болов ч command line tool-ийг ашигладаг. Та төслийн болон апликейшний директорийн бүтцийг үүсгэх, түүнчлэн моделийн янз бүрийн файлуудыг үүсгэхдээ үүнийг ашиглаж байсан. Symfony-н command line нь фреймворкийнхоо дотор нь байдаг учраас шинэ таск нэмж оруулахад маш хялбар.

Хэрэглэгч шинээр ажлын байр оруулаад, түүнийгээ бусдад нээллттэй болгохын тулд идэвхжүүлэх ёстой. Ингэхгүй бол өгөгдлийн бааз нь идэвхгүй ажлын байрны мэдээллүүдээр дүүрэх болно. Иймд өгөгдлийн баазаас идэвхгүй ажлын байруудыг устгах таскийг үүсгэе. Энэ таск нь ихэвчлэн ажлын байрны cron-д дуудагдан ажиллана:

// lib/task/JobeetCleanupTask.class.php

class JobeetCleanupTask extends sfBaseTask

{

protected function configure()

{

$this->addOptions(array(

new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application', 'frontend'),

new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environement', 'prod'),

new sfCommandOption('days', null, sfCommandOption::PARAMETER_REQUIRED, '', 90),

));

$this->namespace = 'jobeet';

$this->name = 'cleanup';

$this->briefDescription = 'Cleanup Jobeet database';

$this->detailedDescription = <<<EOF

The [jobeet:cleanup|INFO] task cleans up the Jobeet database:

[./symfony jobeet:cleanup --env=prod --days=90|INFO]

EOF;

}

protected function execute($arguments = array(), $options = array())

{

$databaseManager = new sfDatabaseManager($this->configuration);

$nb = Doctrine_Core::getTable('JobeetJob')->cleanup($options['days']);

$this->logSection('doctrine', sprintf('Removed %d stale jobs', $nb));

}

}

Таскийн конфигураци нь configure() методод биелдэг. Таск бүр нь namespace:name гэсэн цор ганц хослолыг агуулахын зэрэгцээ аргумент ба сонголтуудтай байж болно.

Илүү олон жишээ харъя гэвэл Symfony-н таск хавтсыг (lib/task/) үз.

jobeet:cleanup таск нь хоёр сонголтыг тодорхойлдог: –env ба –days хэд хэдэн дефаолт утгын хамт.

Энэ таскийг ажиллуулах нь бусад дурын таск дуудахтай ижил:

$ php symfony jobeet:cleanup –days=10 –env=dev

Өгөгдлийн бааз цэвэрлэх код нь бусад кодуудын адил JobeetJobTable классд төвлөрдөг:

// lib/model/doctrine/JobeetJobTable.class.php

public function cleanup($days)

{

$q = $this->createQuery('a')

->delete()

->andWhere('a.is_activated = ?', 0)

->andWhere('a.created_at < ?', date('Y-m-d', time() - 86400 * $days));

return $q->execute();

}

Symfony-н таскууд нь гүйцэтгэлийн үр дүнг илэрхийлсэн утгыг буцаадаг учраас орчинтойгоо сайн зохицож ажилладаг. Та буцаагдах бүхэл тоог таскийнхаа төгсгөлд тодорхой зааж өгч болно.

Маргааш уулзацгаая

Сорилт – энэ бол Symfony-н хэрэгслийн болон философийн зүрх нь юм. Бид өнөөдөр вэбийн боловсруулалтыг хялбар, хурдан, илүү найдвартай болгохын тулд Symfony-н хэрэгслийг хэрхэн ашиглах талаар дахин судаллаа.

Symfony-н формын фреймворк – энэ бол зөвхөн виджет, валидэйтор биш, түүнээс хамаагүй том зүйл: тэр танд формын сорилтын энгийн аргуудыг өгөөд зогсохгүй формууд тань найдвартай хамгаалагдсан гэсэн итгэлийг төрүүлнэ.

Symfony-н гайхамшигтай ертөнцөөр аялах манай аялал өнөөдөр дуусаагүй. Маргааш бид Jobeet-ийн бээкэнд апликейшнийг байгуулна. Бээкэнд интерфейс бол олонхи вэб-төслийн чухал хэсэг бөгөөд Jobeet-ийн хувьд ч мөн адил. Харин бид түүнийг хэрхэн ганц цагийн дотор байгуулах вэ? Маш энгийн – бид Symfony-н админ үүсгэгч фреймворкийг ашиглана. Харин тэр болтол биеэ бодоорой.

« 10 дахь өдөр: Формууд 12 дахь өдөр: Админ үүсгэгч »

Advertisements

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

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