آموزش سیمفونی روز چهارم – کنترل کننده‌ها و نما‌ها

در قسمت قبل دیدید که سیمفونی چگونه بوسیله کم کردن تفاوت‌های بین موتور‌های پایگاه داده و تبدیل عناصر رابطه‌ای به کلاس‌های رابطه‌ای اشیاء، مدیریت پایگاه داده را ساده می‌کند.
امروز قصد داریم تا ماژول job که دیروز ایجاد کردیم را توسعه دهیم. تمام چیزی که مورد نیاز است اینجا لیست شده است:

  • صفحه‌ای برای لیست کردن مشاغل
  • صفحه‌ای برای ایجاد شغل جدید
  • صفحه‌ای برای ویرایش مشاغل موجود
  • صفحه‌ای برای حذف مشاغل

اگرچه کدها برای استفاده حاضر هستند، اما نیاز است تا با بررسی مجدد، قالب‌ها را برای نزدیکی بیشتر Jobeet بهینه کنیم.

ساختار Model View Controllers – MVC

اگر شما تا کنون برای توسعه وب از فریم‌ورکی استفاده نکرده‌اید، احتمالاْ کدهای PHP خود را در قالب صفحات HTML می‌نوشتید.
احتمالاْ شیوه کار این فایل‌ها اینگونه بود: ارزش دهی و پیکره‌بندی کلی، منطق برنامه و رابطه ان با صفحات، بازیابی رکورد‌های پایگاه داده و در نهایت کدهای HTMLی که صفحه را پدید می‌آورند.
ایجاد تغییرات در چنین ساختاری، مخصوصاْ پس از گذشت مدتی بسیار سخت و طاقت فرسا است. و بدتر از آن زمانی است که شخص دیگری قصد ویرایش این کدها را داشته باشد.(کار گروهی)
اما این مشکل راه حل بسیار خوبی دارد.
رایج‌ترین ساختار برای مرتب سازی کدها در طراحی وب الگوی طراحی MVC است. بطور خلاصه، MVC راهی را برای مرتب سازی کد‌های شما با طبیعت خودش، مشخص می‌کند. این الگو کد‌ها را به سه لایه مجزا تقسیم می‌کند:
لایه مدل: منطق برنامه را مشخص می کند، سیمفونی نیز تمام فایل‌های مربوط به این لایه را در lib/model ذخیره می‌کند.
لایه نما: چگونگی نمایش است، (موتور قالب قسمتی از این لایه است) در سیمفونی لایه View بیشتر از کد‌های PHP ساخته می‌شود و در پوشه‌های مختلف template ذخیره می‌شود و در ادامه همین قسمت به آنها خواهیم پرداخت.
لایه کنترل کننده: قسمتی از کد‌ها که وظیفه فراخوانی Model را برای داده‌های عبور داده شده از لایه View را برای رندر شدن کلاینت را برعهده دارد.

چگونگی عملکرد ساختار MVC

چگونگی عملکرد ساختار MVC

هنگامی که در قسمت اول سیمفونی را نصب کردیم، دیدید که چگونه درخواست‌ها بوسیله front controllers مدیریت می‌شدند (index.php and frontend_dev.php).همین front controllers کار اصلی را انجام می‌دهند.
همانطور که دیروز هم دیدید، این عملیات منطقاْ در ماژول‌ها دسته بندی شده‌اند.
امروز با استفاده از مدل آزمایشی مطرح شده در روز دوم، صفحه اصلی و صفحه شغل را تغییر می‌دهیم و انها را پویا می‌کنیم.
در این راه موارد زیادی در فایل‌های مختلفی برای شرح ساختار پوشه‌های سیمفونی بکار می‌بریم و این کد‌ها را بین لایه‌ها تقسیم می‌کنیم.

طرح بندی – Layout

اگر به یک مدل نگاهی کنید، به شباهت اکثر این صفحات به هم پی می‌برید و همچنین می‌دانید که تکرار کد کار درستی نیست، چه کدهای HTML و چه PHP. بنابراین به راهی نیاز داریم تا از این کپی برداری‌ها جلوگیری شود.
یک راه برای این مشکل مشخص کردن هیدر و فوتر و include کردن آنها در هر قالب است.

header_footer

ساختار Header - footer

اما در اینجا فایل‌های هیدر و فوتر شامل HTML معتبری نیستند. راه بهتری هم وجود دارد، بجای اینکار از یک الگوی طراحی دیگر استفاده می‌کنیم الگوی طراحی آذین داخلی (decorator).
این الگو برای حا این مشکل اینگونه عمل می‌کند:
قالب پس از رندر محتوا بوسیله یک قالب سراسری آراسته می‌شود، فراخوان کردن یک layout در سیمفونی.

برای مشاهده ابعاد واقعی کلیک کنید

ساختار layout

Layout پیشفرض یک application فایل layout.php را فراخوانی می‌کند که آن را در مسیر apps/frontend/templates می‌بینید.
این پوشه شامل تمامی قالب‌های سراسری برای application است. کد‌های زیر را با کد‌های موجود در layout.php عوض کنید.

<!-- apps/frontend/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 - Your best job board</title>
    <link rel="shortcut icon" href="/favicon.ico" />
    <?php include_javascripts() ?>
    <?php include_stylesheets() ?>
  </head>
  <body>
    <div id="container">
      <div id="header">
        <div class="content">
          <h1><a href="/job">
            <img src="/images/jobeet.gif" alt="Jobeet Job Board" />
          </a></h1>
 
          <div id="sub_header">
            <div class="post">
              <h2>Ask for people</h2>
              <div>
                <a href="/job/new">Post a Job</a>
              </div>
            </div>
 
            <div class="search">
              <h2>Ask for a job</h2>
              <form action="" method="get">
                <input type="text" name="keywords"
                  id="search_keywords" />
                <input type="submit" value="search" />
                <div class="help">
                  Enter some keywords (city, country, position, ...)
                </div>
              </form>
            </div>
          </div>
        </div>
      </div>
 
      <div id="content">
        <?php if ($sf_user->hasFlash('notice')): ?>
          <div class="flash_notice">
            <?php echo $sf_user->getFlash('notice') ?>
          </div>
        <?php endif; ?>
 
        <?php if ($sf_user->hasFlash('error')): ?>
          <div class="flash_error">
            <?php echo $sf_user->getFlash('error') ?>
          </div>
        <?php endif; ?>
 
        <div class="content">
          <?php echo $sf_content ?>
        </div>
      </div>
 
      <div id="footer">
        <div class="content">
          <span class="symfony">
            <img src="/images/jobeet-mini.png" />
            powered by <a href="http://www.symfony-project.org/">
            <img src="/images/symfony.gif" alt="symfony framework" />
            </a>
          </span>
          <ul>
            <li><a href="">About Jobeet</a></li>
            <li class="feed"><a href="">Full feed</a></li>
            <li><a href="">Jobeet API</a></li>
            <li class="last"><a href="">Affiliates</a></li>
          </ul>
        </div>
      </div>
    </div>
  </body>
</html>

یک قالب سیمفونی، تنها یک فایل ساده PHP است. در طرح‌بندی قالب می‌توانید فانکشن‌های PHP را فراخوانی کنید و به متغیر‌های PHP اشاره کنید. $sf_content متغیر جالبی است که بوسیله خود فریم‌ورک مشخص شده است و شامل کد‌های HTML ساخته شده توسط اکشن‌ها می‌باشد.
اگر شما ماژول Job را مشاهده کنید (http://jobeet.localhost/frontend_dev.php/job)، خواهید دید که تمامی اکشن‌ها بوسیله این طرح آراسته شده‌اند.

سبک‌نامه‌ها، تصاویر و جاوا اسکریپت‌ها – CSS, Images and Java Scripts

این آموزش در مورد طراحی وب نیست بلکه در رابطه با توسعه آن است پس شما می‌توانید تمام موارد لازم برای این پروژه را از آدرس‌های زیر دریافت کنید.
دریافت تصاویر و ذخیره آنها در پوشه web/images
دریافت سبک‌نامه‌ها و ذخیره آنها در پوشه web/css

یادداشت: آیکن برنامه را هم می‌توانید از این ادرس دریافت کنید و در پوشه web ذخیره کنید.

نام

خروجی layout برنامه

نکته: در حالت پیشفرض دستور generate:project سه پوشه جهت ذخیره ملزومات پروژه ایجاد می‌کند: web/images برای تصاویر، web/css برای فایل‌های استایل و پوشه web/js برای فایل‌های جاوا اسکریپت.
این ساختتار فقط یکی از قرارداد هایی است که توسط سیمفونی تعیین شده است، با این حال شما می‌توانید آنها را در هر نقطه‌ای تحت پوشه web ذخیره کنید.

خوانندگان ریزبین متوجه شده‌اند که در هیچ کجای layout اشاره‌ای به فایل‌ main.css نشده است. اما در خروجی HTML آن را مشاهده می‌کنیم! این چگونه ممکن است؟
سبک نامه‌ها بوسیله فانکشن include_stylesheets() در تگ Head فراخوانی شده است. این فانکشن یک کمک‌کننده را فراخوانی می‌کند.
کمک کننده خود یک فانکشن است که توسط سیمفونی تعیین شده است و می‌تواند پارامتر‌هایی را در قالب HTML برگرداند، کمک کننده باعث صرفه‌جویی در وقت می‌شود، آنها بسته‌های کوچکی هستند که خیلی اوقات در قالب بکار برده می‌شوند. کمک‌کننده include_stylesheets()تگ link را برای سبک‌نامه ایجاد می‌کند.
در این قسمت این سوال پیش می‌آید که کمک‌کننده از کجا متوجه می‌شود که کدام سبک‌نامه را باید include‌کند؟ با ویرایش فایل view.yml می‌توان لایه view را پیکره‌بندی نمود.
این پیکره‌بندی پیشفرض است که به کمک دستور generate:app ایجاد شده است:

# apps/frontend/config/view.yml
default:
  http_metas:
    content-type: text/html
 
  metas:
    #title:        symfony project
    #description:  symfony project
    #keywords:     symfony, project
    #language:     en
    #robots:       index, follow
 
  stylesheets:    [main.css]
 
  javascripts:    []
 
  has_layout:     on
  layout:         layout

فایل پیکره‌بندی view.yml بطور پیشفرض تنظیماتی را بروی تمامی قالب‌های application اعمال می‌کند. بعنوان مثال، مقدار stylesheet یک آرایه را برای سبک‌نامه‌هایی که باید در هر صفحه include شوند را مشخص می‌کند.

یادداشت: فایل view.yml به فایل main.css اشاره می‌کند نه به css/main.css. در حقیقت هر دو مشخصه با هم برابر هستند، زیرا مسیر‌های نسبی پیشوندی سیمفونی با /css همراهند.

اگر تعداد فایل‌های زیادی مشخص شده باشند، سیمفونی آنها را در جای مشخص include می‌کند.

stylesheets:    [main.css, jobs.css, job.css]

همچنین می‌توانید media را مشخص کرده و حتی پسوند css را هم حذف کنید!

stylesheets:    [main.css, jobs.css, job.css, print: { media: print }]

خروجی این پیکره‌بندی اینچنین است:

<link rel="stylesheet" type="text/css" media="screen" href="/css/main.css" />
<link rel="stylesheet" type="text/css" media="screen" href="/css/jobs.css" />
<link rel="stylesheet" type="text/css" media="screen" href="/css/job.css" />
<link rel="stylesheet" type="text/css" media="print" href="/css/print.css" />

نکته: فایل view.yml طرح (layout) پیشفرض برای استفاده applicationها را نیز مشخص می‌کند. بطور پیشفرض نام آن layout است و بنابراین سیمفونی تمام صفحات را با فایل layout.php آرایش می‌دهد. همچنین شما می‌توانید این پروسه را با تغییر دادن مقدار has_layout به false کاملاْ غیر فعال کنید.

این رزوش کار می‌کند، اما فایل jobs.css مستلزم به وجود صفحه اصلی و فایل job.css به صفحه شغل می‌باشد. پیکره‌بندی view.yml می‌تواند بر مبنای per-module توسعه یابد. فایل view.yml را طوری تغییر می‌دهیم تا تنها فایل main.css را شامل شود.

# apps/frontend/config/view.yml
stylesheets:    [main.css]

برای توسعه جهت ماژول job یک فایل view.yml با محتوای زیر در مسیر apps/frontend/modules/job/config ایجاد می‌کنیم.

# apps/frontend/modules/job/config/view.yml
indexSuccess:
  stylesheets: [jobs.css]
 
showSuccess:
  stylesheets: [job.css]

در قسمت زیرین indexSuccess و showSuccess (اینها همام اسامی قالب هستند که با اکشن‌های index و show پیوست خورده‌اند، که در آینده بیشتر می‌بینیم) می‌توانید هر ورودی که زیر قسمت default پیدا می‌کنید را در فایل view.yml برنامه (application) توسعه دهید. تمام ورودی‌های خاص با پیکره‌بندی application ترکیب شده‌اند. همچنین شما می‌توانید برخی پیکره‌بندی‌ها را برای تمامی اکشن‌های یک ماژول بوسیله قسمت مخصوص all مشخص کنید.

اصول پیکره‌بندی در سیمفونی

برای بیشتر فایل‌های پیکره‌بندی سیمفونی، همان تنظیمات می‌تواند در سطوح مختلفی مشخص شود.

  • پیکره‌بندی پیشفرض در فریمورک تعیین شده است
  • پیکره‌بندی سراسری برای پروژه (در پوشه config)
  • پیکره‌بندی داخلی برای یک application (در پوشه apps/APP/config)
  • پیکره‌بندی داخلی انحصاری برای یک ماژول (apps/APP/MODULE/config)

در زمان اجرا، سیستم پیکره‌بندی تمام مقادیر را از فایل‌های مختلف در صورت یافتن و cach کردن با هم پیوند می‌دهد تا نتیجه آن بهترین کارایی را داشته باشد.

هنگامی که چیزی بوسیله فایل پیکره‌بندی، پیکره‌بندی شده باشد، همان را می‌توان بوسیله فایل‌های PHP کامل کرد. بجای ایجاد یک فایل view.yml برای ماژول job، بعنوان مثال می‌توان از کمک کننده use_stylesheet() برای include کردن استایل از یک قالب استفاده کرد:

همچنین می‌توانید برای include‌کردن یک استایل سراسری هم از این کمک‌کننده استفاده کنید.
انتخاب یک متد یک موضوع کاملاْ سلیقه‌ای است. فایل view.yml راهی را برای تخصیص مواردی به تمام اکشن‌ها و ماژول‌ها آماده می‌کند که اینکار در یک قالب شدنی نیست. اما با این حال پیکره‌بندی کاملاْ ایستا است و و استفاده از کمک‌کننده‌ها انعطاف زیادی دارد و علاوه بر آن هر چیز سر جای خودش است: مشخصات استایل و کد HTML.
ما برای پروژه jobeet از کمک‌کننده use-stylesheet() استفاده می‌کنیم. به همین علت شما می‌توانید فایل view.yml را حذف کنید.

<!-- apps/frontend/modules/job/templates/indexSuccess.php -->
<?php use_stylesheet('jobs.css') ?>
 
<!-- apps/frontend/modules/job/templates/showSuccess.php -->
<?php use_stylesheet('job.css') ?>

یادداشت: همینطور برای فایل‌های javascript می‌توان از view.yml و یا کمک‌کننده use-javascript() استفاده کرد.

صفحه اصلی job

همانطور که در روز سوم مشاهده کردید، صفحه اصلی job بوسیله اکشن index از ماژول job ایجاد شد. اکشن index یک کنترل‌کننده صفحه است و پیوندی با قالب دارد، فایل indexsuccess.php نیز قسمت view است.

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

اکشن

هر اکشن بوسیله یک مقدار از یک کلاس نمایش داده می‌شود. برای صفحه اصلی job، کلاس jobActions (نام ماژول بهمراه پسوند Actions) و متد executeIndex() (پیشوند execute بهمراه نام اکشن). این تمام مشاغل را از پایگاه داده بازیابی می‌کند:

// apps/frontend/modules/job/actions/actions.class.php
class jobActions extends sfActions
{
  public function executeIndex(sfWebRequest $request)
  {
    $this->jobeet_job_list = JobeetJobPeer::doSelect(new Criteria());
  }
 
  // ...
}

با دقت بیشتری به کد‌ها نگاه کنید: متد executeIndex() (کنترل‌کننده) مدل JobeetJobPeer را برای بازیافت تمامی مشاغل فراخوانی می‌کند.(new Criteria()) این تمام آرایه‌های اشیاء JobeetJob را که به شی jobeet_job_list اشاره دارد را باز می‌گرداند.
تمامی این خصوصیات شیء بطور خودکار از قالب عبور می‌کند (view). برای عبور داده‌ها از controllerها به view تنها یک خاصیت جدید ایجاد می‌شود.

public function executeFooBar(sfWebRequest $request)
{
  $this->foo = 'bar';
  $this->bar = array('bar', 'baz');
}

این کد متغیر‌های $foo و $bar را که در قالب قابل دسترسی هستند را ایجاد می‌کند.

قالب

بطور پیشفرض، نام قالب با توجه به تعداد داده‌های سیمفونی با یک Action یکپارچه شده است.(نام اکشن با پسوندی از success).
قالب indexSuccess.php برای تمامی مشاغل یک جدول HTML ایجاد می‌کند. این کد‌ها را مشاهده کنید:

<!-- apps/frontend/modules/job/templates/indexSuccess.php -->
<?php use_stylesheet('jobs.css') ?>
 
<h1>Job List</h1>
 
<table>
  <thead>
    <tr>
      <th>Id</th>
      <th>Category</th>
      <th>Type</th>
<!-- more columns here -->
      <th>Created at</th>
      <th>Updated at</th>
    </tr>
  </thead>
  <tbody>
    <?php foreach ($jobeet_job_list as $jobeet_job): ?>
    <tr>
      <td>
        <a href="<?php echo url_for('job/show?id='.$jobeet_job->getId()) ?>">
          <?php echo $jobeet_job->getId() ?>
        </a>
      </td>
      <td><?php echo $jobeet_job->getCategoryId() ?></td>
      <td><?php echo $jobeet_job->getType() ?></td>
<!-- more columns here -->
      <td><?php echo $jobeet_job->getCreatedAt() ?></td>
      <td><?php echo $jobeet_job->getUpdatedAt() ?></td>
    </tr>
    <?php endforeach; ?>
  </tbody>
</table>
 
<a href="<?php echo url_for('job/new') ?>">New</a>

در کد قالب، حلقه foreach کلیه اشیاء job را لیست می‌کند.($jobeet_job_list) و برای هر شغل ، هر یک از ستون‌ها مقداری در خروجی دارد. به خاطر داشته باشید که برای دسترسی به مقادیر ستون‌ها راه بسیار راحتی وجود دارد. فراخوانی متد دسترسی که با get شروع می‌شود و سپس نام ستون (فیلد) مورد نظر می‌آید. (به عنوان مثال، getCreatedAt() برای دسترسی به فیلد created_at بکار می‌رود)

<!-- apps/frontend/modules/job/templates/indexSuccess.php -->
<?php use_stylesheet('jobs.css') ?>
 
<div id="jobs">
  <table class="jobs">
    <?php foreach ($jobeet_job_list as $i => $job): ?>
      <tr class="<?php echo fmod($i, 2) ? 'even' : 'odd' ?>">
        <td class="location"><?php echo $job->getLocation() ?></td>
        <td class="position">
          <a href="<?php echo url_for('job/show?id='.$job->getId()) ?>">
            <?php echo $job->getPosition() ?>
          </a>
        </td>
        <td class="company"><?php echo $job->getCompany() ?></td>
      </tr>
    <?php endforeach; ?>
  </table>
</div>
صفحه اصلی پروژه

صفحه اصلی پروژه

در رابطه با تابع url_for() در قسمت بعد صحبت می‌کنیم.

قالب صفحه شغل

حالا نوبت ایجاد قالب صفحه شغل است.
فایل showSuccess.php را باز کرده و محتوای زیر را با محتوای پیشفرض تغییر دهید.

<!-- apps/frontend/modules/job/templates/showSuccess.php -->
<?php use_stylesheet('job.css') ?>
<?php use_helper('Text') ?>
 
<div id="job">
  <h1><?php echo $job->getCompany() ?></h1>
  <h2><?php echo $job->getLocation() ?></h2>
  <h3>
    <?php echo $job->getPosition() ?>
    <small> - <?php echo $job->getType() ?></small>
  </h3>
 
  <?php if ($job->getLogo()): ?>
    <div class="logo">
      <a href="<?php echo $job->getUrl() ?>">
        <img src="/uploads/jobs/<?php echo $job->getLogo() ?>"
          alt="<?php echo $job->getCompany() ?> logo" />
      </a>
    </div>
  <?php endif; ?>
 
  <div class="description">
    <?php echo simple_format_text($job->getDescription()) ?>
  </div>
 
  <h4>How to apply?</h4>
 
  <p class="how_to_apply"><?php echo $job->getHowToApply() ?></p>
 
  <div class="meta">
    <small>posted on <?php echo $job->getCreatedAt('m/d/Y') ?></small>
  </div>
 
  <div style="padding: 20px 0">
    <a href="<?php echo url_for('job/edit?id='.$job->getId()) ?>">
      Edit
    </a>
  </div>
</div>

این قالب از متغیر $job برای نمایش اطلاعات شغل استفاده می‌کند. زیرا ما می‌توانیم متغیر عبور به قالب را از $jobeet_job به $job تغییر نام دهیم، شما هم می‌توانید این تغییر را در اکشن show ایجاد کنید.(دقت کنید که دو رویداد برای این متغیر وجود دارد)

// apps/frontend/modules/job/actions/actions.class.php
public function executeShow(sfWebRequest $request)
{
  $this->job = JobeetJobPeer::retrieveByPk($request->getParameter('id'));
  $this->forward404Unless($this->job);
}

توجه داشته باشید که برخی از لوازم دسترسی Propel آرگومنت‌هایی دریافت می‌کنند. از آنجایی که ستون created_at را از نوع timestamp تعریف کردیم فرمان getCreatedAt() نیازمند قالبی برای تاریخ می‌باشد.

$job->getCreatedAt('m/d/Y');

یادداشت: توضیحات شغل از کمک کننده simple_format_text() برای قالب بندی HTML استفاده می‌کند.
از آنجایی که این کمک‌کننده از خانواده کمک‌کننده‌های text است و بصورت پیشفرض لود نمی‌شود، ما آن را بصورت دستی و با استفاده از کمک کننده use_helper() بارگذاری کردیم.

صفحه نمایش شغل

صفحه نمایش شغل

شیار‌ها

خوب، حالا عنوان همه صفحات را در در تگ title لایه بندی مشخص می‌کنیم.

<title>Jobeet - Your best job board</title>

اما برای صفحه شغل، اطلاعات کاربردی‌تری باید مهیا کنیم. مثل نام شرکت و موقعیت شغل.
در سیمفونی هنگامی که یک ناحیه از layout برای نمایش وابسته به قالب باشد، به شیار‌ها (Slot) نیاز پیدا می‌کنیم.

ساختار شیار‌ها

ساختار شیار‌ها

شیاری را به layout اضافه می‌کنیم تا بتوان عنوان پویا ایجاد کرد.

// apps/frontend/templates/layout.php
<title><?php include_slot('title') ?></title>

هر شیار بوسیله یک نام مشخص می شود و می‌تواند بوسیله کمک‌کننده include_slot() نمایش داده شود. حالا در ابتدای فایل showSuccess.php از کمک‌کننده شیار برای صفحه شغل استفاده می‌کنیم.

// apps/frontend/modules/job/templates/showSuccess.php
<?php slot(
  'title',
  sprintf('%s is looking for a %s', $job->getCompany(), $job->getPosition()))
?>

اگر عنوان مجموعه‌ای برای ایجاد دارد، این کمک‌کننده می‌تواند در بلاکی از کد استفاده شود.

// apps/frontend/modules/job/templates/showSuccess.php
<?php slot('title') ?>
  <?php echo sprintf('%s is looking for a %s', $job->getCompany(), $job->getPosition()) ?>
<?php end_slot(); ?>

برای برخی صفحات همچون صفحه اصلی، تنها به یک عنوان عمومی نیاز است. برای اینکار می‌توانیم یک عنوان پیشفرض برای صفحه مشخص کنیم.

// apps/frontend/templates/layout.php
<title>
  <?php if (!include_slot('title')): ?>
    Jobeet - Your best job board
  <?php endif; ?>
</title>

اگر شیار‌ها مشخص شده باشند، کمک‌کننده مقدار صحیح را باز می‌گرداند، بنابر‌این هنگامی که عنوان خاصی مشخص نشده باشد، مقدار پیشفرض باز می‌گردد.

نکته: در گذشته مشاهده کردید که یک کمک‌کننده با include_ آغاز می‌شود که محتوای HTML تولید می‌کند و در بیشتر موارد همتایی دارد که با get_ آغاز می‌شود و تنها محتوا را بر‌میگرداند.

<?php include_slot('title') ?>
<?php echo get_slot('title') ?>
 
<?php include_stylesheets() ?>
<?php echo get_stylesheets() ?>

اکشن صفحه شغل

این صفحه بوسیله اکشن show در متد executeShow() از ماژول job ایجاد شده‌است.

class jobActions extends sfActions
{
  public function executeShow(sfWebRequest $request)
  {
    $this->job = JobeetJobPeer::retrieveByPk($request->getParameter('id'));
    $this->forward404Unless($this->job);
  }
 
  // ...
}

مانند اکشن index از کلاس JobeetJobPeer که برای بازگرداندن یک شغل استفاده می‌شد، حالا اینکار بوسیله متد retrieveByPk() انجام می‌گیرد.پارامتر این متد شناسه یکتای شغل است همان کلید اصلی. در قسمت بعد توضیح می‌دهیم که برای چه عبارت $request->getParameter(’id’)کلید اصلی شغل را باز‌ می‌گرداند.

نکته: کلاس‌های مدل ایجاد شده متد‌های بسیاری را برای ارتباط متقابل با اشیاء پروژه دارند. مدتی را صرف مطالعه کد‌های موجود در پوشه lib/om کنید تا به قدرت نهفته در آن پی ببرید.

اگر شغلی در پایگاه داده یافت نشد، کاربر را به صفحه ۴۰۴ می‌بریم. که در حقیقت کار متد forward404Unless() است.
این متد یک مقدار بولی بعنوان اولین آرگومنت می‌گیرد و اگر مقدار صحیح باشد، اجرای فعلی را متوقف می‌کند.
در حالت‌های خاص صفحه بنمایش درآمده برای کاربران متفاوت است. محیط prod و محیط dev را در تصاویر زیر مشاهده می‌کنید:

صفحه ۴۰۴ در محیط prod

صفحه ۴۰۴ در محیط prod

صفحه ۴۰۴ در محیط dev

صفحه ۴۰۴ در محیط dev

یادداشت: قبل از قرار دادن jobeet در سرور اصلی باید بدانید که چگونه می‌توان صفحه ۴۰۴ را ویرایش کرد.

خانواده متد‌های forward

فراخوانی forward404Unless در حقیقت برابری می‌کند با :

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

که همچنین با این نیز برابری دارد:

if (!$this->job)
{
  $this->forward404();
}

متد forward404() تنها یک shortcut برای این است:

$this->forward('default', '404');

متد forward() به سمت یک اکشن دیگر از همان application هدایت می‌کند، همچنان که در مثال قبلی به اکشن ۴۰۴ ماژول default.
ماژول default همراه سیمفونی است و اکشن‌های پیشفرض را برای ۴۰۴، صفحات secure و صفحه لوگین مهیا می‌کند.

درخواست‌ها و جواب‌ها

هنگامی که در مرورگرتان صفحه /job و یا /job/show/id/1 را مرور می‌کنید، گردشی را براه انداخته‌اید. مرورگر درخواست‌ می‌دهد و سرور پاسخگویی باز می‌گرداند.
در گذشته دیدید که سیمفونی در‌خواست‌ها را در آبجکت sfWebRequest کپسوله می‌کند.(به متدexecuteShow() نگاهی بیندازید) و علاوه بر آن سیمفونی یک فریم‌ورک شیءگرا است. جواب‌ها هم یک آبجکت از کلاس sfWebResponse هستند. می‌توانید با فراخوانی $this->getResponse() به آبجکت پاسخ دسترسی داشته باشید. این اشیاء متد‌های مناسب زیادی برای دسترسی به اطلاعات توابع و متغیر‌های سراسری PHP تولید می‌کند.

درخواست‌ها

کلاس sfWebRequest کلیه آرایه‌های سراسری PHP از قبیل $_SERVER, $_COOKIE, $_GET, $_POST, and $_FILES می‌باشد.

Method name PHP equivalent
getMethod() $_SERVER['REQUEST_METHOD']
getUri() $_SERVER['REQUEST_URI']
getReferer() $_SERVER['HTTP_REFERER']
getHost() $_SERVER['HTTP_HOST']
getLanguages() $_SERVER['HTTP_ACCEPT_LANGUAGE']
getCharsets() $_SERVER['HTTP_ACCEPT_CHARSET']
isXmlHttpRequest() $_SERVER['X_REQUESTED_WITH'] == 'XMLHttpRequest'
getHttpHeader() $_SERVER
getCookie() $_COOKIE
isSecure() $_SERVER['HTTPS']
getFiles() $_FILES
getGetParameter() $_GET
getPostParameter() $_POST
getUrlParameter() $_SERVER['PATH_INFO']
getRemoteAddress() $_SERVER['REMOTE_ADDR']

قبلاْ با استفاده از متد getParameter() به پارامتر‌های درخواست‌ دسترسی پیدا کردیم که مقداری را از متغیر‌های سراسری GET، POST و یا PATH_INFO بر‌میگرداند.
اگر می‌خواهید مطمئن باشید کا مقادیر از متغیر خاصی می‌آیند باید به ترتیب از متد‌های getGetParameter(), getPostParameter(), and getUrlParameter() استفاده کنید.

یادداشت: هنگامی که قصد محدود‌کردن اکشن به متدی خاص را دارید، برای مثال همنگامی که می‌خواهید اطمینان حاصل کنید که یک فرم بوسیله POST ارسال شده است، می‌توانید از متد isMethod() استفاده کنید:

$this-&gt;forwardUnless($request-&gt;isMethod('POST'));

پاسخ‌ها

کلاس sfWebResponse متد‌های header() و setrawcookie() را پوشش می‌دهد.

Method name PHP equivalent
setCookie() setrawcookie()
setStatusCode() header()
setHttpHeader() header()
setContentType() header()
addVaryHttpHeader() header()
addCacheControlHttpHeader() header()

مسلماْ کلاس sfWebResponse راهی را برای آماده کردن محتوای پاسخ (setContent()) و ارسال آن به مرورگر(send()) را ایجاد می‌کند.
بالاتر در رابطه با مدیریت CSSها و Jsها در فایل view.yml و قالب صحبت کردیم. در آخر هر دو تکنیک در جوابگویی شیء addStylesheet() و addJavascript() استفاده شدند.

نکته: کلاس‌های sfAction ، sfRequest و sfResponse متد‌های مفید و بسیار زیادی تولید می‌کنند. به این لینک مراجعه کنید تا بیشتر در رابطه با کلاس‌های داخلی سیمفونی بدانید.

فردا همدیگر را می‌بینیم

امروز به شرح الگوی طراحی استفاده شده در سیمفونی پرداختیم، کار با قالب را شروع و Layout و فایل‌های قالب را دستکاری کردیم. همچنین کمی آنها را پویا کردیم و این کار را به لطف شیار‌ها و اکشن‌ها انجام دادیم.
فردا در رابطه با url_for() که امروز بکار بردیم و یکپارچه کردن با مسیر‌یابی را فرا‌خواهیم گرفت.

(2) دیدگاه || دیدگاه شما چیست؟

حمیدرضا در تاریخ 29 می , 2009 @ 11:03 ب.ظ

من 4 تا مطلب مربوط به این موضوع را خواندم خیلی جالب و مفید بود.
می خواستم ببینم شما می توانید کتابی یا doc یا هرچیه دیگه مربوط به propel , doctrine معرفی کنید مهم نیست سطحش چه جور باشه فقط قابل فهم باشه.

مهدی در تاریخ 1 ژوئن , 2009 @ 7:52 ب.ظ

سلام
یه موضوع به من بار‌ها ثابت شده، اونم اینه که بهترین راه برای فرا‌گیری همچین چیزایی doc موجود تو وب‌سایت رسمی پروژه هست. دلیلشم اینه که توسعه دهندگانش مطمئناْ تمام سعی خودشون رو می‌کنند که کاربرای بیشتری رو جذب کنند و در نتیجه بهترین و قابل فهم‌ترین آموزش‌ها رو توی سایت رسمی منتشر می‌کنند.
برای Propel هم اینجاس
بابت بازخورد ممنونم.
موفق باشید…

دیدگاه خود را بگوئید

D:

قدرت این وبلاگ از وردپرس فارسی است، طراح قالب خودم هستم. با معرفت‌ها اجازه استفاده از مطالب رو دارند.

این صفحه توسط 33 پرس و جو در عرض 4052 ثانیه ایجاد شده است و از نظر زبان فارسی کاملاً معتبر می‌باشد.