<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Moshtaghi.ir &#187; php</title>
	<atom:link href="http://weblog.moshtaghi.ir/category/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://weblog.moshtaghi.ir</link>
	<description>وبلاگ شخصی مهدی مشتاقی</description>
	<lastBuildDate>Mon, 01 Mar 2010 10:48:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.2</generator>
	<language>fa</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>کتاب مرجع برای سیمفونی</title>
		<link>http://weblog.moshtaghi.ir/2009/07/symfony-reference-book/</link>
		<comments>http://weblog.moshtaghi.ir/2009/07/symfony-reference-book/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 22:04:55 +0000</pubDate>
		<dc:creator>مهدی</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[کتاب الکترونیکی]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.moshtaghi.ir/weblog/?p=430</guid>
		<description><![CDATA[اگر خواننده ثابت وبلاگ من باشید به احتمال زیاد می‌دانید که Symfony  یک فریم‌ورک قدرتمند برای توسعه وب است. فریم‌ورکی که به نظر من سختی کار را تا حدی کم می‌کند که طراحی اولیه جداول برنامه مشکل‌ترین و وقت‌گیر ترین قسمت توسعه برنامه می شود. (که آن هم به برکت Eclipse و پلاگین‌هایش و فرمت ]]></description>
			<content:encoded><![CDATA[<p>اگر خواننده ثابت وبلاگ من باشید به احتمال زیاد می‌دانید که Symfony  یک فریم‌ورک قدرتمند برای توسعه وب است. فریم‌ورکی که به نظر من سختی کار را تا حدی کم می‌کند که طراحی اولیه جداول برنامه مشکل‌ترین و وقت‌گیر ترین قسمت توسعه برنامه می شود. (که آن هم به برکت <a href="http://eclipse.org/" target="_blank">Eclipse</a> و <a href="http://sfdt.borox.ch/" target="_blank">پلاگین‌هایش</a> و فرمت YAML تا حد زیادی راحت شده است)<br />
<img class="alignleft size-full wp-image-13" title="symfony_reference_mini" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/07/symfony_reference_mini.jpg" alt="symfony_reference_mini" width="220" height="275" /><br />
برای انجام دادن توسعه با این فریم‌ورک سخت‌ترین قسمت، یادگیری آن است که باز هم به برکت <a href="http://symfony-project.org/" target="_blank">سایت رسمی پروژه</a> بسیار راحت شده زیرا راه‌های مختلفی همچون خود آموز‌ها، فیلم‌ها و کتاب‌های زیادی را آماده کرده‌اند که در <a href="http://www.symfony-project.org/doc/1_2/" target="_blank">اینجا</a> می‌توانید ببینید. بنده هم چند وقتی است که علاقمند به یادگیری این فریم‌ورک شده‌ام و تا جایی که توانسته‌ام خودآموز Jobeet را ترجمه کرده‌ام و انشالله این کار را ادامه خواهم داد.</p>
<p>نکته اصلی اینجاست که برای شروع این خودآموز‌ها بسیار خوب هستند ولی وقتی که می‌خواهیم پروژه خودمان را انجام دهیم به مشکل بر می‌خوریم. زیرا احتمالاْ سوالاتی پیش می‌آید که جواب آنها در این خود‌آموز‌ها نیست و یا حدالقل بصورت واضح وجود ندارد.</p>
<p>اینجاست که جای خالی یک کتاب مرجع برای سیمفونی و پیکره‌بندی‌های آن حس می‌شود که باز هم سایت رسمی اینکار را انجام داده است و کتابی را تحت عنوان<em> «کتاب مرجع سیمفونی» که به لاتین «</em>The symfony Reference Book» می‌شود <a href="http://www.symfony-project.org/reference/1_2/en/" target="_blank">منتشر کرده است</a>.</p>
<h3>عنوان بخش‌های این کتاب عبارتند از:</h3>
<p><span id="more-430"></span></p>
<ul class="intro" style="text-align:left; direction:ltr;">
<li><a href="http://www.symfony-project.org/reference/1_2/en/01-Introduction" target="_blank">Introduction</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/02-YAML" target="_blank">The YAML Format</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/03-Configuration-Files-Principles" target="_blank">Configuration File Principles</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/04-Settings" target="_blank">The settings.yml Configuration File</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/05-Factories" target="_blank">The factories.yml Configuration File</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/06-Admin-Generator" target="_blank">The generator.yml Configuration File</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/07-Databases" target="_blank">The databases.yml Configuration File</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/08-Security" target="_blank">The security.yml Configuration File</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/09-Cache" target="_blank">The cache.yml Configuration File</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/10-Routing" target="_blank">The routing.yml Configuration File</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/11-App" target="_blank">The app.yml Configuration File</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/12-Filters" target="_blank">The filters.yml Configuration File</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/13-View" target="_blank">The view.yml Configuration File</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/14-Other-Configuration-Files" target="_blank">Other Configuration Files</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/15-Events" target="_blank">Events</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/16-Tasks" target="_blank">Tasks</a></li>
<li><a href="http://www.symfony-project.org/reference/1_2/en/A-License" target="_blank">Appendix A &#8211; License</a></li>
</ul>
<p>همچنین می‌تونید نسخه PDF این کتاب رو با حجم نا قابل 1.2Mb از <a href="http://www.symfony-project.org/get/pdf/reference-1.2-en.pdf">اینجا</a> دریافت کنید.</p>
<img src="http://www.moshtaghi.ir/weblog/?ak_action=api_record_view&id=430&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.moshtaghi.ir/2009/07/symfony-reference-book/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>استفاده از وردپرس به عنوان یک فریم‌ورک PHP</title>
		<link>http://weblog.moshtaghi.ir/2009/07/use-wordpress-as-a-php-framework/</link>
		<comments>http://weblog.moshtaghi.ir/2009/07/use-wordpress-as-a-php-framework/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 20:52:41 +0000</pubDate>
		<dc:creator>مهدی</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[وردپرس]]></category>
		<category><![CDATA[Customization]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[resource]]></category>

		<guid isPermaLink="false">http://www.moshtaghi.ir/weblog/?p=422</guid>
		<description><![CDATA[وردپرس یک راه حل عالی برای راه اندازی وبلاگ است که از پس هر کاری بر می‌آید. قدرت باور نکردنی این پلتفرم امکان توسعه یک وبسایت شخصی را در کمترین زمان و کمترین زحمت ایجاد می‌کند. (نکته‌ای بسیار مهم در طراحی و توسعه وب)
در این مقاله می‌بینید که چگونه بوسیله ورد‌پرس، وبسایتی حرفه ای ایجاد ]]></description>
			<content:encoded><![CDATA[<p><a title="وب‌سایت رسمی وردپرس" href="http://wordpress.org" target="_blank">وردپرس</a> یک راه حل عالی برای راه اندازی وبلاگ است که از پس هر کاری بر می‌آید. قدرت باور نکردنی این پلتفرم امکان توسعه یک وبسایت شخصی را در کمترین زمان و کمترین زحمت ایجاد می‌کند. (نکته‌ای بسیار مهم در طراحی و توسعه وب)<br />
در این مقاله می‌بینید که چگونه بوسیله ورد‌پرس، وبسایتی حرفه ای ایجاد کنید. تنها کافی است تا کمی HTML بدانید، در این صورت به ادامه مطلب توجه کنید.</p>
<h3>تمامی پلتفرم در یک صفحه PHP</h3>
<p>برای شروع اینکار ملزوماتی نیاز است همچون وردپرس نصب شده، کمی اطلاعات راجع به HTML که خیلی بهتر می‌شود اگر راجع به PHP هم بدانید و یک ادیتور HTML تا کدها را در آن ویرایش کنید. (برای این منظور Eclipse گزینه فوق‌العاده‌ای می باشد که <a title="انتخاب یک IDE مناسب php و سازگاری آن با symfony (قسمت اول)" href="http://www.moshtaghi.ir/weblog/2009/06/best-php-ide-and-compatible-with-symfony/">قبلا مورد بحث بوده است</a>) اما یک ادیتور ساده هم نیاز ما را رفع می‌کند.<br />
وردپرس روی صفحات PHP کار می‌کند، اما شمایی که اطلاعاتی راجع به PHP ندارید نگران نباشید زیرا برای هدف ما همان HTML کافی است.<br />
<span id="more-422"></span><br />
فایلی با نام test.php ایجاد کنید و آن را در پوشه ریشه وبلاگ خود قرار دهید. (همان پوشه‌ای که فایل‌هایی از قبیل wp-config.php، wp-ligin.php و یا … در آن قرار دارند)<br />
حالا قطعه کد زیر را در خط اول فایل خود کپی کنید</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span>’wp<span style="color: #339933;">-</span>blog<span style="color: #339933;">-</span><span style="color: #990000;">header</span><span style="color: #339933;">.</span>php’<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>با همین قطعه کد ساده تمامی ویژگی‌ها، دستورات و توابع وردپرس را در این صفحه فعال می‌سازید! برای آزمایش آن می‌توانید کدهای زیر را به فایل خود اضافه کنید.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span>’wp<span style="color: #339933;">-</span>blog<span style="color: #339933;">-</span><span style="color: #990000;">header</span><span style="color: #339933;">.</span>php’<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&lt;html&gt;
&lt;body&gt;
&lt;div class=”name”&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bloginfo<span style="color: #009900;">&#40;</span>’name’<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/div&gt;
&lt;div class=”description”&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bloginfo<span style="color: #009900;">&#40;</span>’description’<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></div></div>

<p>سپس فایل را  ذخیره کرده و آن را در مرورگر خود مشاهده کنید. برای مثال اگر آدرس وب‌سایت شما http://moshtaghi.ir باشد، می‌توانید صفحه مذکور را در آدرس http://moshtaghi.ir/test.php مشاهده کنید.<br />
در این صفحه شما می‌توانید نام و توضیحات مربوط به وب‌سایت خود را که از پایگاه داده استخراج شده‌اند را مشاهده کنید.</p>
<h3>نوشتن یک صفحه وب کامل در ۱۰ ثانیه</h3>
<p>اینکه صفحات ایجاد شده به این روش از نظر ظاهری با قالب اصلی وب‌سایت سازگاری داشته باشند خیلی مهم است، اما پیاده سازی قالب فعلی وب‌سایت در قالب HTML کار راحتی نیست و البته قرار هم نیست تا آن را دوباره ایجاد کنیم!<br />
برای اینکار تنها کافیست تا کد زیر را در صفحه مورد نظر کپی کرده و ذخیره کنیم.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span>’wp<span style="color: #339933;">-</span>blog<span style="color: #339933;">-</span><span style="color: #990000;">header</span><span style="color: #339933;">.</span>php’<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> get_header<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&lt;!– Put here your personal contents in HTML or PHP –&gt;
…
&lt;!– End personal contents –&gt;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> get_footer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>در این صفحه با استفاده از توابع get_header و get_footer می‌توانید هیدر و فوتر وب‌سایت (قالب فعلی) خود را بکار بگیرید، پس تنها کافیست تا محتوای اصلی صفحه را ایجاد کرده و فایل را ذخیره کنید.<br />
حتی می‌توانید ساید‌بار فعلی قالب را هم به این صورت و با استفاده از تابع get_sidebar بکار بگیرید.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span>’wp<span style="color: #339933;">-</span>blog<span style="color: #339933;">-</span><span style="color: #990000;">header</span><span style="color: #339933;">.</span>php’<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> get_header<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&lt;!– Put here your personal contents in HTML or PHP –&gt;
…
&lt;!– End personal contents –&gt;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> get_sidebar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> get_footer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>اگر راجع به توابع وردپرس نمی‌دونید و یا دوست دارید بیشتر بدونید به <a title="مرجع فارسی توابع وردپرس برای طراحان وب" href="http://gonahkar.com/archives/1383/10/08/wordpress-persian-reference/" target="_blank">این آدرس</a> و <a href="http://codex.wordpress.org/Main_Page" target="_self">این آدرس</a> مراجعه کنید که اولی وبلاگ گناهکار عزیز و بعدی هم داکیومنشن‌های اصلی وردپرس می‌باشند.<br />
کار خیلی راحت بود ولی سوالی شاید برای بعضی‌ها پیش آمده باشد که:</p>
<h3>چرا و چه هنگام باید برای ایجاد صفحه وب از وردپرس استفاده کنیم؟</h3>
<p>برخی موارد را می‌توان بوسیله یک تابع وردپرس و یا یک افزونه در صفحه‌ای بکار برد، بنابراین هنگامی که شما فایل wp-blog-header.php را در صفحه خود include می‌کنید، می‌توانید از وردپرس به عنوان یک فریم‌ورک عالی برای توسعه وب‌سایت خود استفاده کنید.<br />
سوالی که پیش می‌آید این است که «چرا از برگه‌های ساده وردپرس بهمراه قالبی خاص استفاده نکنیم؟»<br />
بله، می‌توان اینکار را کرد و البته در برخی موارد بهترین راه حل است. اما بزرگترین مزیت این سیستم، داشتن کنترل کامل بروی صفحه است. می‌توانید تنها افزونه‌، اسکریپتی خاص و یا هر آنچه به ذهنتان می‌رسد را نمایش دهید. می‌شود به کل سایدبار را حذف کرد و یا جای ان را تغییر داد و … . می شود اینها را با استفاده از برگه‌های وردپرس هم انجام داد اما باید سختی‌ها و پیچیدگی‌های زیادی را متحمل شد.</p>
<h3>چه کارهایی را می‌توان با این تکنیک انجام داد؟</h3>
<p>هر کاری که بخواهید را می‌توانید با این شیوه انجام دهید، اما معمول‌ترین و عقلانی‌ترین آنها عبارتند از:</p>
<ul>
<li> هنگامی که وبلاگی دارید و می‌خواهید وب‌سایتی را کنار ان داشته باشید و به آن بسط دهید.</li>
<li> هنگامی که از یک قالب وردپرسی خوشتان آمده باشد و بخواهید برای وب‌سایت خود از آن استفاده کنید.</li>
<li> هنگامی که بخواهید تبلیغی را برای نتایج جستجو روی یک صفحه خود اعمال کنید.</li>
<li> هنگامی که بخواهید یک <strong>Application</strong> کوچک را در کنار وبلاگ خود اضافه کنید.</li>
</ul>
<p>و در نهایت به شما پیشنهاد می‌کنم حتماْ از این ویژگی عالی که وردپرس برای ما به ارمغان اورده است استفاده کنید تا قدرت سرشار فریم‌ورکی همچون ورد‌پرس را شاهد باشید و اگر ایده‌ای خاص در زمینه کاربرد این شیوه دارید <strong>حتماْ با من در میان بگذارید</strong>. ممنون می‌شم.</p>
<p>منبع این مطلب <a href="http://www.problogdesign.com/wordpress/use-wordpress-as-a-php-framework-for-your-static-html-pages/">اینجاس</a></p>
<p><strong>پ‌ن: </strong>امروزه طراحی و توسعه وب بازار مناسب و تقریباْ دست نخورده‌ای دارد که هر کس می‌تواند به آن وارد شود، اما لازمه آن سرعت بالا در یادگیری و اجرا می‌باشد. با سرعت بالا در یادگیری کاری ندارم اما تنها راه رسیدن به سرعت بالا در اجرا و پیاده‌سازی استفاده از فریم‌ورک‌ها می‌باشد. حال این فریم‌ورک به سادگی WP باشد یا به عظمت <a href="http://symfony-project.org/">Symfony</a>، چه فریم‌ورکی برای PHP باشد، یا <a href="http://jquery.com" target="_blank">فریم‌ورکی برای JS</a> و یا حتی CSS.</p>
<img src="http://www.moshtaghi.ir/weblog/?ak_action=api_record_view&id=422&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.moshtaghi.ir/2009/07/use-wordpress-as-a-php-framework/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>سیمفونی فینالیست شد</title>
		<link>http://weblog.moshtaghi.ir/2009/06/symfony-were-finalist/</link>
		<comments>http://weblog.moshtaghi.ir/2009/06/symfony-were-finalist/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 12:47:30 +0000</pubDate>
		<dc:creator>مهدی</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[اینترنت]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Sourceforge]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.moshtaghi.ir/weblog/?p=417</guid>
		<description><![CDATA[چند هفته پیش در سایت Sourceforge حرکتی مبنی بر انتخاب بهترین پروژه‌های کدباز در رده‌های مختلف به راه افتاد. توسعه دهندگان و کاربران زیادی در این انتخاب (شاید هم رقابت انتخاباتی!!!) شرکت کردند، سیمفونی نیز یکی از این پروژه‌های کدباز بود که با پشتیبانی و کمک کاربرانش توانست در ۳ گروه فینالیست باشد که این ]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-570" title="cca_logo" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/06/cca_logo.png" alt="cca_logo" width="205" height="323" />چند هفته پیش در سایت Sourceforge حرکتی مبنی بر انتخاب بهترین پروژه‌های کدباز در رده‌های مختلف به راه افتاد. توسعه دهندگان و کاربران زیادی در این انتخاب (شاید هم رقابت انتخاباتی!!!) شرکت کردند، سیمفونی نیز یکی از این پروژه‌های کدباز بود که با پشتیبانی و کمک کاربرانش توانست در ۳ گروه فینالیست باشد که این گروه‌ها عبارتند از:</p>
<ul class="intro">
<li>بهترین پروژه!</li>
<li>بهترین ابزار یا برنامه برای توسعه دهندگان</li>
<li>بهترین پروژه برای کسب و کار</li>
</ul>
<p>شما هم می‌توانید برای کمک، <a href="http://sourceforge.net/community/cca09/vote/" target="_blank">در سایت Sourceforge به سیمفونی رای دهید</a> و سپس با نوشتن مطالبی مرتبط با سیمفونی در وبلاگ خود، توییتر و یا هرجایی که خودتان می‌دانید در معرفی و گسترش این فریم‌ورک قدرتمند سهیم باشید. (حدالقل <a href="http://twitter.com/fabpot/statuses/2283369961" target="_blank">این را دوباره توییت کنید</a>، تو رو خدا!!!) <img src='http://www.moshtaghi.ir/weblog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p><a href="http://www.symfony-project.org/blog/2009/06/22/sourceforge-community-choice-awards-symfony-is-a-finalist" target="_blank">این مطلب در وبلاگ سیمفونی</a></p>
<img src="http://www.moshtaghi.ir/weblog/?ak_action=api_record_view&id=417&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.moshtaghi.ir/2009/06/symfony-were-finalist/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>آموزش سیمفونی روز ششم – مطالب بیشتری از لایه مدل</title>
		<link>http://weblog.moshtaghi.ir/2009/06/6th-symfony-jobeet/</link>
		<comments>http://weblog.moshtaghi.ir/2009/06/6th-symfony-jobeet/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 11:30:06 +0000</pubDate>
		<dc:creator>مهدی</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[jobeet]]></category>
		<category><![CDATA[model layer]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.moshtaghi.ir/weblog/?p=400</guid>
		<description><![CDATA[دیروز روز مهمی بود. یاد گرفتیم که چگونه URLهای زیاد بسازیم و اینکه چگونه از سیمفونی برای خودکار سازی موارد زیادی استفاده کنیم. امروز با پیچیده کردن کد‌ها، قابلیت‌های بهتری به jobeet اضافه می‌کنیم. شما در طول این فرایند، اطلاعات بیشتری راجع به تمامی ویژگی‌هایی که در روز پنجم به آن اشاره شد دریافت می‌کنید.
ضوابط ]]></description>
			<content:encoded><![CDATA[<p>دیروز روز مهمی بود. یاد گرفتیم که چگونه URLهای زیاد بسازیم و اینکه چگونه از سیمفونی برای خودکار سازی موارد زیادی استفاده کنیم. امروز با پیچیده کردن کد‌ها، قابلیت‌های بهتری به jobeet اضافه می‌کنیم. شما در طول این فرایند، اطلاعات بیشتری راجع به تمامی ویژگی‌هایی که در روز پنجم به آن اشاره شد دریافت می‌کنید.</p>
<h3>ضوابط شیء Propel</h3>
<p>با توجه به قوانین روز دوم:<br />
« هنگامی که کاربری به سایت وارد می‌شود، لیستی از مشاغل فعال را مشاهده می‌کند»<br />
اما در حال حاضر تمامی مشاغل لیست می‌شوند، چه فعال باشند و چه &#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// apps/frontend/modules/job/actions/actions.class.php</span>
<span style="color: #000000; font-weight: bold;">class</span> jobActions <span style="color: #000000; font-weight: bold;">extends</span> sfActions
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeIndex<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">jobeet_job_list</span> <span style="color: #339933;">=</span> JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">doSelect</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Criteria<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>یک شغل فعال نباید بیشتر از ۳۰ روز پیش پست شده باشد. متد doSelect یک شیء Criteria را می‌گیرد که همان شرح در‌خواست پایگاه داده برای اجرا است.<span id="more-400"></span><br />
در کد بالا، متد Criteria بصورت خالی عبور داده شده، که به معنی برگشت دادن تمامی رکورد‌های موجود در جدول می‌باشد.<br />
حالا آن را طوری تغییر می‌دهیم که تنها مشاغل فعال را برگرداند:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeIndex<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$criteria</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Criteria<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span>JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">CREATED_AT</span><span style="color: #339933;">,</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">86400</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">30</span><span style="color: #339933;">,</span> Criteria<span style="color: #339933;">::</span><span style="color: #004000;">GREATER_THAN</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">jobeet_job_list</span> <span style="color: #339933;">=</span> JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">doSelect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$criteria</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>متد Criteria::add یک شرط Where را به SQL ساخته شده اضافه می‌کند. در اینجا Criteria را برای تنها بازگرداندن مشاغل فعال محدود کردیم. متد add عملگر‌های مقایسه زیادی را پشتیبانی می‌کند، که پرکاربرد‌ترین آنها را مشاهده می‌کنید:</p>
<ul class="intro" style="text-align: left; direction : ltr;">
<li>Criteria::EQUAL</li>
<li>Criteria::NOT_EQUAL</li>
<li>Criteria::GREATER_THAN, Criteria::GREATER_EQUAL</li>
<li>Criteria::LESS_THAN, Criteria::LESS_EQUAL</li>
<li>Criteria::LIKE, Criteria::NOT_LIKE</li>
<li>Criteria::CUSTOM</li>
<li>Criteria::IN, Criteria::NOT_IN</li>
<li>Criteria::ISNULL, Criteria::ISNOTNULL</li>
<li>Criteria::CURRENT_DATE, Criteria::CURRENT_TIME, Criteria::CURRENT_TIMESTAMP</li>
</ul>
<h3>اشکال‌زدایی SQLهای ایجاد شده توسط propel</h3>
<p>با توجه به اینکه شما کدهای SQL را بطور دستی ایجاد نمی‌کنید، propel آنها را با توجه به موتور پایگاه داده‌ای که در روز سوم معرفی کردید ایجاد می‌کند. اما بعضی اوقات، مشاهده کدهای SQL ایجاد شده توسط propel می‌تواند بسیار سودمند باشد. برای مثال جهت اشکال‌زدایی یک query که به درستی کار نمی‌کند. در محیط dev سیمفونی این queryها را ثبت می‌کند (به همراه بسیاری از موارد دیگر). برای هر مجموعه از application و محیط یک فایل log وجود دارد. محتوای فایل frontend_dev.log را مشاهده کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># log/frontend_dev.log</span>
Dec <span style="color: #cc66cc;">6</span> <span style="color: #cc66cc;">15</span>:<span style="color: #cc66cc;">47</span>:<span style="color: #cc66cc;">12</span> symfony <span style="color: #66cc66;">&#91;</span>debug<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#123;</span>sfPropelLogger<span style="color: #66cc66;">&#125;</span> exec: SET NAMES 'utf8'
Dec <span style="color: #cc66cc;">6</span> <span style="color: #cc66cc;">15</span>:<span style="color: #cc66cc;">47</span>:<span style="color: #cc66cc;">12</span> symfony <span style="color: #66cc66;">&#91;</span>debug<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#123;</span>sfPropelLogger<span style="color: #66cc66;">&#125;</span> prepare: SELECT jobeet_job.ID, jobeet_job.CATEGORY_ID, jobeet_job.<span style="color: #000000; font-weight: bold;">TYPE</span>, jobeet_job.COMPANY, jobeet_job.LOGO, jobeet_job.<span style="color: #000066;">URL</span>, jobeet_job.POSITION, jobeet_job.LOCATION, jobeet_job.DESCRIPTION, jobeet_job.HOW_TO_APPLY, jobeet_job.TOKEN, jobeet_job.IS_PUBLIC, jobeet_job.CREATED_AT, jobeet_job.UPDATED_AT FROM `jobeet_job` WHERE jobeet_job.CREATED_AT<span style="color: #66cc66;">&gt;</span>:p1
Dec <span style="color: #cc66cc;">6</span> <span style="color: #cc66cc;">15</span>:<span style="color: #cc66cc;">47</span>:<span style="color: #cc66cc;">12</span> symfony <span style="color: #66cc66;">&#91;</span>debug<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">&#123;</span>sfPropelLogger<span style="color: #66cc66;">&#125;</span> Binding '<span style="color: #cc66cc;">2008</span>-<span style="color: #cc66cc;">11</span>-06 <span style="color: #cc66cc;">15</span>:<span style="color: #cc66cc;">47</span>:<span style="color: #cc66cc;">12</span>' at position :p1 w<span style="color: #66cc66;">/</span> PDO <span style="color: #000000; font-weight: bold;">type</span> PDO::PARAM_STR</pre></div></div>

<p>اینجا می‌توانید SQL ایجاد شده خودتان توسط propel را که به همراه شرطی که بروی ستون created_at اعمال می‌شود مشاهدی کنید. (WHERE jobeet_job.CREATED_AT &gt; :p1)</p>
<blockquote><p><strong>یادداشت</strong>: رشته p1 در query نشان دهنده شرح بیان شده SQL ایجاد شده توسط propel است. مقدار واقعی p1 (در مثال بالا «2008-11-06 15:47:12» ) در هنگام اجرای query ثبت می‌شود و بطور صحیح بوسیله موتور پایگاه داده گریز داده می‌شود. استفاده از این عبارات آماده شده، قابل نمایش بودن را برای حملات SQL injection کم می‌کند.</p></blockquote>
<p>این عالیست، اما سوئیچ کردن بین مرورگرها، IDEها و فایل‌های log کمی آزار دهنده است. اینگونه باید بصورت مداوم یک تغییر را آزمایش کنید. از نوار ابزار اشکال‌زدایی symfony ممنونیم، تمام اطلاعاتی که نیاز دارید براحتی در مرورگر در دسترس می‌باشد.</p>
<p style="text-align: center;"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/06/web_debug_sql.png"><img class="aligncenter size-large wp-image-556" title="web_debug_sql" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/06/web_debug_sql-490x41.png" alt="web_debug_sql" width="490" height="41" /></a></p>
<h3>ترتیب شیء</h3>
<p>کد بالا به هنگام کار کردن، نتیجه بعیدی از چیزی که در روز دوم تعریف کردیم را می‌دهد:<br />
«یک کاربر می‌تواند برگردد و دوباره شغل خود را فعال کند و زمان انقضای آن را از ۳۰ روز بیشتر کند &#8230;»<br />
اما ایم کد تنها به مقدار موجود در فیلد created_at تکیه می‌کند، و چون این ستون تنها زمان ایجاد رکورد را ثبت می‌کند نمی‌توانیم این قابلیت را بر مبنای آن پیاده کنیم.<br />
اما اگر نمای پایگاه داده‌ای که در روز سوم ایجاد کردیم را بخاطر بیاورید، یک ستون به نام expires_at نیز مشخص شده بود. و مقدار پیشفرض برای آن در اطلاعات پایه در نظر گرفته نشد. این ستون می‌تواند بصورت خودکار مقدار ۳۰ روز پس از تاریخ ثبت را بگیرد.<br />
هنگامی که نیاز است تا برخی مقادیر بصورت خودکار و مرتب بر مبنای پایگاه داده، قبل از یک شیء ایجاد شوند، می‌توانید متد save از کلاس مدل را مهم‌تر کنید.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/model/JobeetJob.php</span>
<span style="color: #000000; font-weight: bold;">class</span> JobeetJob <span style="color: #000000; font-weight: bold;">extends</span> BaseJobeetJob
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> save<span style="color: #009900;">&#40;</span>PropelPDO <span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isNew</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getExpiresAt</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$now</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCreatedAt</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCreatedAt</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'U'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setExpiresAt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$now</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">86400</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">30</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>متد isnew هنگامی که شیء هنوز در پایگاه داده مرتب سازی نشده، مقدار true و در غیر این صورت false را بر می‌گرداند.<br />
حالا اکشن را طوری تغییر می‌دهیم تا بجای created_at از فیلد expires_at استفاده کند:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeIndex<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$criteria</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Criteria<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span>JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">EXPIRES_AT</span><span style="color: #339933;">,</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> Criteria<span style="color: #339933;">::</span><span style="color: #004000;">GREATER_THAN</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">jobeet_job_list</span> <span style="color: #339933;">=</span> JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">doSelect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$criteria</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>به این صورت، query را برای انتخاب بر حسب ویژگی expires_at محدود کردیم.</p>
<h3>اطلاعات بیشتر راجع داده‌های اولیه</h3>
<p>Refresh کردن صفحه اصلی، تغییری در پی ندارد. زیرا این مشاغل همین چند روز پیش پست شده‌اند. این تغییرات را ایجاد کنید تا مشاغلی که expires شده‌اند را به جدول بیفزائید:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># data/fixtures/020_jobs.yml</span>
JobeetJob:
  <span style="color: #808080; font-style: italic;"># other jobs</span>
&nbsp;
  expired_job:
    category_id:  programming
    company:      Sensio Labs
    position:     Web Developer
    location:     Paris, France
    description:  <span style="color: #66cc66;">|</span>
      Lorem ipsum dolor sit amet, consectetur
      adipisicing elit.
    how_to_apply: Send your <span style="color: #000000; font-weight: bold;">resume</span> to lorem.ipsum <span style="color: #66cc66;">&#91;</span>at<span style="color: #66cc66;">&#93;</span> dolor.sit
    is_public:    true
    is_activated: true
    expires_at:   <span style="color: #cc66cc;">2005</span>-<span style="color: #cc66cc;">12</span>-01
    token:        job_expired
    email:        job<span style="color: #66cc66;">@</span>example.com</pre></div></div>

<blockquote><p><strong>یادداشت</strong>: کد‌ها را به دقت کپی کنید تا فرورفتگی‌ها از بین نرود. expires_job تنها دو تا Space قبل از خود دارد.</p></blockquote>
<p>همانطور که شغل اصافه شده را در فایل fixture می‌بینید، مقدار ستون created_at مشخص شده است. حتی اگر بطور خودکار توسط propel پر شود.<br />
مقدار مشخص شده بر هر مقدار پیشفرضی اولویت دارد. Fixture را دوباره بارگذاری کنید و صفحه را refresh کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">$ php symfony propel:data-load</pre></div></div>

<p>می‌توانید query زیر را برای مطمئن شدن از اینکه ستون expires_at بطور پیشفرض توسز متد save و بر مبنای ستون created_at مقدار دهی می‌شوند را اجرا کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">`position`</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">`created_at`</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">`expires_at`</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #ff0000;">`jobeet_job`</span>;</pre></div></div>

<h3>پیکره‌بندی دستی</h3>
<p>در متد JobeetJob::save بوسیله کدهای پیچیده‌ای تعداد روزهای فعال بودن را مشخص کردیم. اما خیلی بهتر است تا این مقدار را قابل پیکره‌بندی کنیم.<br />
Symfony برای هر application یک فایل پیکره‌بندی ایجاد می‌کند تا ویژگی‌های خاص در آن تعریف شود. فایل app.yml می‌تواند شامل هر تنظیمی که شمما می‌خواهید باشد.</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># apps/frontend/config/app.yml</span>
all:
  active_days: <span style="color: #cc66cc;">30</span></pre></div></div>

<p>در application، این تنظیمات بوسیله کلاس سراسری sfConfig در دسترس هستند.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app_active_days'</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>تنظیمات بهمراه پیشوند app_ هستند، زیرا کلاس sfConfig علاوه بر این دسترسی به تنظیمات symfony را هم مهیا می‌کند، که در آینده می‌بینیم.<br />
کدها را بروز می‌کنیم تا تنظیمات جدید اعمال شود.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> save<span style="color: #009900;">&#40;</span>PropelPDO <span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isNew</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getExpiresAt</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$now</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCreatedAt</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCreatedAt</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'U'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setExpiresAt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$now</span> <span style="color: #339933;">+</span> <span style="color: #cc66cc;">86400</span> <span style="color: #339933;">*</span> sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app_active_days'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> parent<span style="color: #339933;">::</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>فایل پیکره‌بندی app.yml راه فوق‌العاده‌ای برای متمرکز کردن تنظیمات سراسری application شما می‌باشد.<br />
در آخر، اگر نیاز به تعریف تنظیمات سراسری گسترده‌تری دارید، تنها یک فایل app.yml در پوشه config ریشه ایجاد کنید و &#8230;</p>
<h3>دوباره سازی &#8211; Refactoring</h3>
<p>اگر چه این کد کار مورد نظر را انجام می‌دهد، اما راه سریعی نیست. آیا می‌توانید مشکل آن را بیابید؟<br />
کد Criteria متعلق به اکشن نیست (لایه کنترل) بلکه متعلق به لایه مدل است. در ساختار MVC، لایه مدل تمام منطق برنامه را مشخص می‌کند و لایه کنترل تنها لایه مدل را برای بازیافت داده‌ها فراخوانی می‌کند. از آنجایی که این کد مجموعه‌ای از مشاغل را بر می‌گرداند، آن را به کلاس JobeetJobPeer انتقال می‌دهیم و متدی بنام getActiveJobs ایجاد می‌کنیم:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/model/JobeetJobPeer.php</span>
<span style="color: #000000; font-weight: bold;">class</span> JobeetJobPeer <span style="color: #000000; font-weight: bold;">extends</span> BaseJobeetJobPeer
<span style="color: #009900;">&#123;</span>
  static <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getActiveJobs<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$criteria</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Criteria<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">EXPIRES_AT</span><span style="color: #339933;">,</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> Criteria<span style="color: #339933;">::</span><span style="color: #004000;">GREATER_THAN</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">doSelect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$criteria</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>حالا کد اکشن می‌تواند از این متد برای بازیافت مشاغل استفاده کند.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeIndex<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">jobeet_job_list</span> <span style="color: #339933;">=</span> JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">getActiveJobs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>این دوباره سازی چندین مزیت نسبت به کد قبل داشت:</p>
<ul>
<li>
منظق دریافت مشاغل فعال حالا در لایه مدل قرار دارد، جایی که به آن متعلق است.
</li>
<li>
کد موجود در قسمت کنترل بسیار خوانا‌تر از قبل است.
</li>
<li>
متد getActiveJobs می‌تواند دوباره مورد استفاده قرار گیرد (برای مثال در سایر اکشن‌ها)
</li>
<li>
کد لایه مدل حالا یک واحد قابل آموزش است.
</li>
</ul>
<p>حالا مرتب سازی مشاغل را بر حسب ستون expired_at صورت می‌دهیم.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">static <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getActiveJobs<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$criteria</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Criteria<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">EXPIRES_AT</span><span style="color: #339933;">,</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> Criteria<span style="color: #339933;">::</span><span style="color: #004000;">GREATER_THAN</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addDescendingOrderByColumn</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">EXPIRES_AT</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">doSelect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$criteria</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>متد addDescendingOrderByColumn یک شرط ORDER BY به SQL ایجاد شده اضافه می‌کند. (متد addAscendingOrderByColumn هم وجود دارد)</p>
<h3>دسته‌ بندی‌های صفحه اصلی</h3>
<p>طبق قوانین روز دوم:<br />
«مشاغل بر حسب دسته‌بندی و سپس بر حسب تاریخ انتشارشان لیست می‌شود (ابتدا مشاغل جدید تر)»<br />
تا حالا، دسته‌بندی شغل را در اشتراک نمی‌گرفتیم. مطابق قوانین، صفحه اصلی باید مشاغل را بر حسب دسته‌بندی‌ نمایش دهد. ابتدا باید تمام دسته‌بندی‌ها را با کمترین شغل فعال دریافت کنیم.<br />
کلاس JobeetCategoryPeer را باز کنید و متد getWithJobs را به آن اضافه کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/model/JobeetCategoryPeer.php</span>
<span style="color: #000000; font-weight: bold;">class</span> JobeetCategoryPeer <span style="color: #000000; font-weight: bold;">extends</span> BaseJobeetCategoryPeer
<span style="color: #009900;">&#123;</span>
  static <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getWithJobs<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$criteria</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Criteria<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addJoin</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">ID</span><span style="color: #339933;">,</span> JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">CATEGORY_ID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span>JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">EXPIRES_AT</span><span style="color: #339933;">,</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> Criteria<span style="color: #339933;">::</span><span style="color: #004000;">GREATER_THAN</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setDistinct</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">doSelect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$criteria</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>متد Criteria::addJoin یک شرط JOIN را به SQL اضافه می‌کند. بصورت پیشفرض شرط JOIN به یک شرط WHERE اضافه می‌شود. در ضمن شما می‌توانید عملوند JOIN را با اضافه کردن ۳ آرگومنت زیر تغییر دهید.<br />
(Criteria::LEFT_JOIN ، Criteria::RIGHT_JOIN و  Criteria::INNER_JOIN)<br />
بنابراین اکشن index را تغییر می‌دهیم:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// apps/frontend/modules/job/actions/actions.class.php</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeIndex<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">categories</span> <span style="color: #339933;">=</span> JobeetCategoryPeer<span style="color: #339933;">::</span><span style="color: #004000;">getWithJobs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>در قالب، احتیاج داریم تا حلقه‌ای برای مرور همه دسته‌بندی‌ها و حلقه‌ای برای مرور مشاغل فعال داخل آنها داشته باشیم:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">// apps/frontend/modules/job/indexSuccess.php
<span style="color: #000000; font-weight: bold;">&lt;?php</span> use_stylesheet<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jobs.css'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
&lt;div id=&quot;jobs&quot;&gt;
  <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$categories</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$category</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    &lt;div class=&quot;category_<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> Jobeet<span style="color: #339933;">::</span><span style="color: #004000;">slugify</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$category</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;
      &lt;div class=&quot;category&quot;&gt;
        &lt;div class=&quot;feed&quot;&gt;
          &lt;a href=&quot;&quot;&gt;Feed&lt;/a&gt;
        &lt;/div&gt;
        &lt;h1&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$category</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/h1&gt;
      &lt;/div&gt;
&nbsp;
      &lt;table class=&quot;jobs&quot;&gt;
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$category</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getActiveJobs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$job</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
          &lt;tr class=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #990000;">fmod</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> ? <span style="color: #0000ff;">'even'</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'odd'</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;
            &lt;td class=&quot;location&quot;&gt;
              <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLocation</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
            &lt;/td&gt;
            &lt;td class=&quot;position&quot;&gt;
              <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> link_to<span style="color: #009900;">&#40;</span><span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPosition</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'job_show_user'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$job</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
            &lt;/td&gt;
            &lt;td class=&quot;company&quot;&gt;
              <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCompany</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
            &lt;/td&gt;
          &lt;/tr&gt;
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endforeach</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
      &lt;/table&gt;
    &lt;/div&gt;
  <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endforeach</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&lt;/div&gt;</pre></div></div>

<blockquote><p><strong>یادداشت</strong>: برای نمایش نام دسته‌بندی در قالب از echo استفاده کردیم. جالب نیست؟ $category یک شیء است و ما بطور خارق‌العاده‌ای آن را echo می‌کنیم! جواب این سوال در طول روز سوم بیان شد، هنگامی که متد __toString را برای تمامی کلاس‌های مدل تعریف کردیم.</p></blockquote>
<p>برای اینکار باید متد getActiveJobs را به کلاس JobeetCategory اضافه کنیم. تا مشاغل فعال را از شیء دسته‌بندی باز گرداند.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/model/JobeetCategory.php</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getActiveJobs<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$criteria</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Criteria<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span>JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">CATEGORY_ID</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">getActiveJobs</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$criteria</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>در فراخوانی add، آرگومنت سوم را از قلم انداختیم زیرا Criteria::EQUAL مقدار پیشفرض است.<br />
متد JobeetCategory::getActiveJobs برای برگرداندن مشاغل فعال از دسته بندی انتخابی از متد JobeetJobPeer::getActiveJobs استفاده می‌کند.<br />
هنگامی که شما JobeetJobPeer::getActiveJobs را فراخوانی می‌کنید، محدودیتی برای هموار کردن بوسیله یک دسته‌بندی ایجاد می‌کنیم. در عوض عبور شیء دسته بندی، قطعاْ یک شیء Criteria را عبور می‌دهیم. چون این بهترین راه برای کپسوله کردن یک شرط است.<br />
GetActiveJobs نیاز دارد تا آرگومنت Criteria را با ضوابط (criiteria) خود یکی کند. چون Criteria یک شیء است، کار کاملاْ راحتی است.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/model/JobeetJobPeer.php</span>
static <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getActiveJobs<span style="color: #009900;">&#40;</span>Criteria <span style="color: #000088;">$criteria</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_null</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$criteria</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$criteria</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Criteria<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span>JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">EXPIRES_AT</span><span style="color: #339933;">,</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> Criteria<span style="color: #339933;">::</span><span style="color: #004000;">GREATER_THAN</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addDescendingOrderByColumn</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">EXPIRES_AT</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">doSelect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$criteria</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>حدود نتایج</h3>
<p>هنوز هم قوانینی برای اعمال شدن به لیست مشاغل صفحه اصلی وجود دارد:<br />
«برای هر دسته بندی، تنها ۱۰ لینک می‌توانند در لیست نمایش داده شوند و یک پیوند امکان لیست شدن تمام مشاغل در یک دسته بندی را ایجاد می‌کند»<br />
اینکار بوسیله استفاده از متد getActiveJobs راحت می‌شود.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/model/JobeetCategory.php</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getActiveJobs<span style="color: #009900;">&#40;</span><span style="color: #000088;">$max</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$criteria</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Criteria<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span>JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">CATEGORY_ID</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setLimit</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$max</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">getActiveJobs</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$criteria</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>اختصاص دادن شرط LIMIT در مدل کار سختی است، اما بهتر است تا این مقدار قابلیت پیکره‌بندی داشته باشد. تغییراتی را در قالب ایجاد می‌کنیم تا نهایت مقدار نمایش مشاغل را از فایل app.yml بخواند.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt;!-- apps/frontend/modules/job/indexSuccess.php --&gt;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$category</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getActiveJobs</span><span style="color: #009900;">&#40;</span>sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app_max_jobs_on_homepage'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$job</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>و این تنظیمات را در فایل app.yml اضافه کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">all:
  active_days:          <span style="color: #cc66cc;">30</span>
  max_jobs_on_homepage: <span style="color: #cc66cc;">10</span></pre></div></div>

<p style="text-align: center;"><img class="aligncenter size-large wp-image-559" title="homepage" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/06/homepage-490x362.png" alt="homepage" width="490" height="362" /></p>
<h3>داد‌های اولیه پویا</h3>
<p>برای اینکه نتایج تغییرات را مشاهده کنید، باید گروهی از داده‌های اولیه را وارد سیستم کنیم. می‌توان اطلاعات موجود در fixture را کپی کرد که شاید وقت‌گیر و کسل کننده باشد. Symfony اینکار را هم آسان کرده است. شما می‌توانید از کد‌های php در فایل‌های yml استفاده کنید. فایل 020_jobs.yml را باز کرده و کد‌های زیر را در انتهای آن اضافه کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">JobeetJob:
# Starts at the beginning of the line (no whitespace before)
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">100</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;=</span> <span style="color: #cc66cc;">130</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  job_<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$i</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>:
    category_id:  programming
    company:      Company <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$i</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    position:     Web Developer
    location:     Paris, France
    description:  Lorem ipsum dolor sit amet, consectetur adipisicing elit.
    how_to_apply: |
      Send your resume to lorem.ipsum [at] company_<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$i</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>.sit
    is_public:    true
    is_activated: true
    token:        job_<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$i</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    email:        job@example.com
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endfor</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>دقت کنید که دندانه‌ها و فرورفتگی‌ها را رعایت کنید زیرا در غیر این صورت پردازش نمی‌شوند.<br />
این نکات را همیشه بخاطر بسپارید:</p>
<ul>
<li>
عبارت &lt;?php ?&gt; همیشه باید در ابتدای خط و یا درون یک مقدار جاگذاری شده باشد.
</li>
<li>
اگر یک عبارت &lt;?php ?&gt; سطر را تمام کند، باید در خروجی مقدار «\n» را ذکر کنیم.
</li>
</ul>
<p>و می‌بینیم که در صفحه اصلی تنها ۱۰ شغل آخر اضافه شده است.</p>
<p><img class="aligncenter size-large wp-image-561" title="pagination" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/06/pagination-490x381.png" alt="pagination" width="490" height="381" /></p>
<h3>ایمن کردن صفحه شغل</h3>
<p>هنگامی که شغلی به انقضاء می‌رسد، حتی اگر شما url آن را بدانید نباید به آن دسترسی پیدا کنید. سعی کنید تا URL یک شغل تاریخ گذشته را پیدا کنید. (id را با یک id واقعی در پایگاه داده عوض کنید)</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">SELECT id, token FROM jobeet_job WHERE expires_at <span style="color: #66cc66;">&lt;</span> NOW<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #66cc66;">/</span>frontend_dev.php<span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>sensio-labs<span style="color: #66cc66;">/</span>paris-france<span style="color: #66cc66;">/</span>ID<span style="color: #66cc66;">/</span>web-developer-expired</pre></div></div>

<p>بجای نمایش شغل باید به صفحه ۴۰۴ منتقل شویم. اما چگونه می‌توان بصورت خودکار و بوسیله مسیر‌ها به این نتیجه رسید؟<br />
بطور پیشفرض sfPropelRoute از متد استاندارد doSelectOne برای بازگداندن اشیاء استفاده می‌کند، و ما می‌توانیم مشروط بر اینکه خصیصه method_for_criteria در پیکره‌بندی مسیر باشد آن را تغییر دهیم:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># apps/frontend/config/routing.yml</span>
job_show_user:
  <span style="color: #000066;">url</span>:     <span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>:company_slug<span style="color: #66cc66;">/</span>:location_slug<span style="color: #66cc66;">/</span>:id<span style="color: #66cc66;">/</span>:position_slug
  class:   sfPropelRoute
  options:
    model: JobeetJob
    <span style="color: #000000; font-weight: bold;">type</span>:  <span style="color: #000066;">object</span>
    method_for_criteria: doSelectActive
  param:   <span style="color: #66cc66;">&#123;</span> module: job, action: show <span style="color: #66cc66;">&#125;</span>
  requirements:
    id: \d+
    sf_method: <span style="color: #66cc66;">&#91;</span>GET<span style="color: #66cc66;">&#93;</span></pre></div></div>

<p>متد doSelectActive یک شیء Criteria را که بوسیله مسیر ساخته شده را دریافت می‌کند:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/model/JobeetJobPeer.php</span>
<span style="color: #000000; font-weight: bold;">class</span> JobeetJobPeer <span style="color: #000000; font-weight: bold;">extends</span> BaseJobeetJobPeer
<span style="color: #009900;">&#123;</span>
  static <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> doSelectActive<span style="color: #009900;">&#40;</span>Criteria <span style="color: #000088;">$criteria</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span>JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">EXPIRES_AT</span><span style="color: #339933;">,</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> Criteria<span style="color: #339933;">::</span><span style="color: #004000;">GREATER_THAN</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">doSelectOne</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$criteria</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>حالا، اگر سعی کنید تا شغل تاریخ گذشته‌ای را ببینید با صفحه ۴۰۴ مواجه می‌شوید.</p>
<p><img class="aligncenter size-large wp-image-562" title="exception" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/06/exception-490x381.png" alt="exception" width="490" height="381" /></p>
<h3>پیوند به صفحه مشاغل</h3>
<p>حالا، یک پیوند برای صفحه دسته‌بندی اضافه کرده و این صفحه را ایجاد می‌کنیم. اما صبر کنید! وقت امروز تمام شده و زمان کافی برای ادامه این بحث را نداریم. البته اگر شما زمان کافی را داشته باشید، اطلاعات لازم برای اینکار را هم دارید. سعی کنید تا اینکار را انجام دهید و یا فردا بهمراه یکدیگر انجامش دهیم.</p>
<h3>فردا همدیگر را می‌بینیم</h3>
<p>روی jobeet خود کار کنید، سعی کنید نهایت استفاده از مستندات API و مستندات آزاد موجود در سایت symfony را ببرید. فردا دوباره همدیگر را می‌بینیم و به ادامه کار می‌پردازیم.<br />
موفق باشید&#8230;</p>
<img src="http://www.moshtaghi.ir/weblog/?ak_action=api_record_view&id=400&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.moshtaghi.ir/2009/06/6th-symfony-jobeet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>انتخاب یک IDE مناسب php و سازگاری آن با symfony (قسمت اول)</title>
		<link>http://weblog.moshtaghi.ir/2009/06/best-php-ide-and-compatible-with-symfony/</link>
		<comments>http://weblog.moshtaghi.ir/2009/06/best-php-ide-and-compatible-with-symfony/#comments</comments>
		<pubDate>Mon, 08 Jun 2009 11:57:02 +0000</pubDate>
		<dc:creator>مهدی</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[ابزار طراحی وب]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.moshtaghi.ir/weblog/?p=389</guid>
		<description><![CDATA[اگر به پست‌های قبلی که راجع به توسعه وب توسط php و البته فریم‌ورک بسیار قدرتمند symfony بود علاقه‌ای داشته باشید و آنها رو دنبال کنید، صد در صد برای ویرایش کد‌ها از یک ادیتور همچون gedit، kedit و یا شاید notepad استفاده کرده باشید. و در اینصورت متوجه شدید که دیگر نمی‌توان کار با ]]></description>
			<content:encoded><![CDATA[<p>اگر به پست‌های قبلی که راجع به توسعه وب توسط <a href="http://php.net" target="_blank">php</a> و البته فریم‌ورک بسیار قدرتمند <a href="http://symfony-project.org/" target="_blank">symfony</a> بود علاقه‌ای داشته باشید و آنها رو دنبال کنید، صد در صد برای ویرایش کد‌ها از یک ادیتور همچون <a href="http://projects.gnome.org/gedit/" target="_blank">gedit</a>، kedit و یا شاید notepad استفاده کرده باشید. و در اینصورت متوجه شدید که دیگر نمی‌توان کار با سیمفونی رو روی این قبیل ویرایشگرها ادامه داد.<br />
اینجاست که واجب می‌شود تا برای ادامه کار از یک <a title="Integrated development environment" href="http://en.wikipedia.org/wiki/Integrated_development_environment" target="_blank">IDE</a> خوب استفاده کنید. البته انتخاب IDE مناسب کار راحتی نیست و البته در عین حال راحته!!! یعنی دامنه انتخاب زیاده و شما باید برای انتخاب بهترین IDE، این دامنه رو کوچک‌تر کنید.<br />
برای کوچک کردن این دامنه باید توقع خود را از IDE بالا ببرید. در ادامه مطلب به بررسی این توقعات می‌پردازیم.<br />
<img class="aligncenter size-full wp-image-527" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/06/ides_best.png" alt="ides_best" width="577" height="299" /><br />
<span id="more-389"></span></p>
<h3>رنگ‌بندی کدها &#8211; Syntax highlighting</h3>
<p>رنگ‌بندی درست کد‌ها خوانایی آن را تا حد بسیاری بالا می‌برد. البته این ویژگی روی تمامی IDEها و حتی editor‌ها وجود داره. (جز Notepad ویندوز که بدرد یادداشت نوشتن هم نمی‌خوره!!!)</p>
<h3>اتمام خودکار کد &#8211; Code completion</h3>
<p>این ویژگی به سرعت کد‌نویسی خیلی کمک می‌کنه، همونطور که خیلی‌ها می‌دونند مثلاْ  برای نوشتن قطعه کد مربوط به مقصد یک لینک تنها حرف h را تایپ می‌کنید و IDE مقادیر href=&#8221;" و hreflang=&#8221;" رو به شما پیشنهاد می‌کنه.<br />
البته این ویژگی روی کد‌های php هم به همین صورتی که در تصویر زیر مشاهد می‌کنید اعمال می‌شود.<br />
<img class="aligncenter size-full wp-image-534" title="code_completion" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/06/code_completion.png" alt="code_completion" width="353" height="166" /><br />
پس تا اینجا تمام ادیتور‌ها از دامنه بزرگی که مورد بحث بود حذف شدن. (قابل توجه افرادی که گیر دادن به gedit و Kedit و emEditor و Notepad++ و همین قسم ویرایشگر‌ها)</p>
<h3>ناوبری &#8211; Navigation</h3>
<p>خیلی اوقات پیش می‌آید که شما داخل کد‌ها گم می‌شوید (مخصوصاْ به هنگام توسعه برنامه‌های نوشته شده در گذشته و یا کار‌های گروهی) و نیاز دارید تا برنامه شما رو به محل مورد نظر هدایت کنه. برای اینکار می‌توانید از امکان search یا Find که توی هر ویرایشگری پیدا می‌شه استفاده کنید. اما اگر پروژه کمی بزرگ باشد، دچار مشکل می‌شوید و آن زمان است که به امکانات بیشتری برای جستجو و ناوبری احتیاج پیدا می‌کنید. امکاناتی از قبیل Goto که می‌تونه شما رو به سطر، متد و یا کلاس خاصی هدایت کند (بر حسب کلمه کلیدی و یا تعریف از قبل). و یا پنلی که فایل شما را بر حسب کلاس‌ها و توابع موجود در آن بخش بندی و لیست می‌کند و &#8230;<br />
راستش این قسمت خیلی قابل توضیح دادن نیست و به قول معروف : حلوای تن تنانی، تا نخوری ندانی!!!</p>
<h3>نمایش خطا‌ها و اخطارها</h3>
<p>اشتباهات نحوی syntax و یا حتی غلط‌های املایی برنامه‌نویسی (منظورم از این واژه اختراعی اشتباهاتی همچون جا انداختن آکولاد و امثال این است) مشکلی است که به وفور پیش می‌آید. پس یک IDE خوب باید آنها را تشخیص داده و به شما اعلام کند و گیر خود را تا زمان تصحیح پابرجا نگه دارد.</p>
<h3>دوباره سازی و سازندگی کد &#8211; Refactoring and code generation</h3>
<p>این ویژگی، از آن ویژگی‌هایی است که به هیچ شکلی نمی‌شه از آن گذشت! بعضی اوقات پیش می‌آید که مجبور به دوباره نویسی و یا تغییر مکان کلاس‌ها، توابع و یا شاید فایل‌ها هستیم و اینکار در پروژه‌های کوچک هم کار راحتی به حساب نمی‌آید. چه برسد به &#8230;<br />
سه امکان refactoring که بیشتر به کار می‌آید رو در زیر لیست کردم:</p>
<ul>
<li> Move که تمام includeها و requireها را به هنگام انتقال فایلی از جایی به جای دیگر بروز می‌کند تا مشکلی در روند اجرای پروژه پیش نیاد.</li>
<li> Rename که این اطمینان را می‌دهد که از تغییر نام هر چیزی هیچ مشکلی برای پروژه پیش نخواهد آمد.</li>
<li> Safe delete که شما را مطمئن می‌کند که حذف یک فایل پروژه آسیبی به سایر قسمت‌ها وارد نمی‌کند.</li>
</ul>
<p>علاوه بر این برخی IDEها امکان ایجاد کد‌های مربوط به ساخت توابع سازنده، گیرنده‌ها و &#8230; را نیز فراهم می‌کنند.</p>
<h3>اشکال‌زدایی &#8211; Debugging</h3>
<p>معمولاْ کد‌نویسان php برای اشکال‌زدایی کد‌ها از دستور echo و die استفاده می‌کنند. اما این شیوه هرگز جای اشکال‌زدایی خط‌به‌خط را برای برنامه‌نویس نمی‌تواند پر کند. مخصوصاْ در برنامه‌های بزرگ‌تر. یک IDE خوب این امکان را برای کدنویس مهیا می‌کند.</p>
<h3>سیستم کنترل نسخه &#8211; Versioning system</h3>
<p>این سیستم می‌تواند در هر دو شیوه توسعه فردی و گروهی مفید باشد. این ویژگی امکان مقایسه کد فعلی را با نسخه‌های پیشین بصورت تصویری ایجاد می‌کند. همچنین امکان کپی کردن تغییرات به سایر ورژن‌ها و برگشتن به وضعیت قبلی و ادغام تغییرات ایجاد شده توسط سایر اعضاء تیم را هم برای ما مهیا می‌کند.<br />
<img class="aligncenter size-full wp-image-537" title="code_diff" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/06/code_diff.png" alt="code_diff" width="546" height="214" /><br />
هنگامی که شما تغییرات را چک کرده و آنها را اعمال نمودید، یکی کردن IDE با سیستم‌های کنترل نسخه‌ای همچون CVS، SVN و &#8230; بسیار بهتر از اجرای یک برنامه جدا برای کار با آنها می‌باشد.</p>
<h3>خصوصیات سمت مشتری &#8211; Client-side features</h3>
<p>کمتر پیش می‌آید تا کد‌های  php بصورت جدا نوشته شوند و معمولاْ به همراه کد‌های HTML و همچنین CSS و java script می‌آیند. در نتیجه امکان Code complation برای این قسم کد‌ها در فایل‌های php می‌تواند بسیار سودمند و پرکاربرد باشد.</p>
<h3>کدام IDE تمام این ویژگی‌ها را شامل می‌شود؟</h3>
<p>همانطور که می‌دانید در دنیای متن‌باز برنامه‌های بسیار پر قدرت و مفیدی یافت می شوند. در زمینه IDEها هم می‌توان به جرات گفت که بهترین IDEها OpenSource هستند.<br />
با اندکی دیکتاتوری و بدون هیچ توضیحی ۲ دسته را اینجا نام می‌بریم:</p>
<h4>IDEهای مبتنی بر Eclipse</h4>
<p>فکر می‌کنم <a href="http://www.eclipse.org/" target="_blank">پلتفرم Eclipse</a> معرف حضور بیشتر دوستان باشد، افزونه‌های بسیاری نیز برای کار با php روی Eclipse وجود دارند که برخی از آنها عبارتند از: <a href="http://www.eclipse.org/pdt/" target="_blank">PDT</a>، <a href="http://www.zend.com/products/studio/" target="_blank">Zend Studio</a>، <a href="http://www.aptana.com/php" target="_blank">Aptana PHP</a> و همچنین <a href="http://aptana.com/studio#content_pro" target="_blank">Aptana Studio Pro</a> .<br />
نکته: Aptana را می‌توان بصورت مجزا از Eclipse هم نصب کرد</p>
<h4><a href="http://www.netbeans.org/" target="_blank">NetBeans</a></h4>
<p>این IDE تقریباْ نو ظهور هم، بسیار مناسب می‌باشد و البته برای کار روی Eclipse ساخته نشده است. بیشتر ویژگی‌های سایر IDEها را دارد و خوشبختانه OpenSource هم می‌باشد. با توجه به توسعه سریع، روان و جالب آن آینده بسیار روشنی را پیش روی دارد.</p>
<h3>نتیجه اخلاقی</h3>
<p>آقای الکساندر ماکارو (Alexander Makarov) در مجله <a href="http://www.smashingmagazine.com" target="_blank">Smashing</a>، بررسی جالبی بین این IDEها انجام دادند که به شما پیشنهاد می‌کنم حتماْ آن را <a href="http://spreadsheets.google.com/ccc?key=pV8XyUSUOM7ET07rn4n7NYA" target="_blank">از این آدرس</a> مطالعه کنید.<br />
بنده شخصاْ بعد از مشاهده این مقایسه و تست کردن دو افزونه Aptana و PDT به این نتیجه رسیدم که با همون PDT کار کنم. چون اگر حقیقت را بخواهید همین PDT هم کلی از سرم زیاده و خیلی امکانات دارد که هنوز نشناخته‌ام، اما فکر می‌کنم Aptana امکانات جانبی بیشتری نسبت به PDT دارد. امکانات و ویژگی‌های Zend Studio هم که غیر قابل انکار است، اما من پول ندارم. NetBeans هم مطمئناْ چیز خوبی است چون توی یکی از توییت‌های <a href="http://alvanweb.com" target="_blank">مرتضی الوانی</a> خوندم که از اون استفاده می‌کنه.<br />
در هر صورت انتخاب من، فعلاْ Eclipse و پلاگین PDT است و با آن راحتم. بهترین شیوه برای نصب آن هم استفاده از بسته <a href="http://www.eclipse.org/pdt/downloads/" target="_blank">PDT All In One</a> است. با حجم تقریبی 140mb که بعد از Extract کردن آماده استفاده است. بروی کلیه پلتفرم‌های لینوکس ۳۲ و ۶۴، مکینتاش و ویندوز هم قابل اجرا می‌باشد. (<a href="http://www.eclipse.org/pdt/downloads/" target="_blank">از این آدرس می‌توانید نسخه مناسب با سیستم خود را دریافت کنید</a>)</p>
<h3>و اما ادامه ماجرا</h3>
<p>تا کنون به نتیجه نسبتاْ خوبی برای قسمت اول عنوان این پست رسیدیم، یعنی IDE خود را برای کار با php انتخاب کردیم. اما برای کار با سیمفونی باید تا حدودی IDE را با خواسته‌های خود سازگار کنیم. اینکار را به بخش‌های مختلفی همچون symfony code completion در PDT، ایجاد رنگ‌بندی برای فایل‌های YAML و استفاده از پلاگین Subclipse برای کار با SVN تقسیم می‌کنیم که در قسمت دوم این مقاله به شرح آن خواهیم پرداخت.</p>
<p><a href="http://weblog.alvanweb.com/2008/11/26/setting-up-eclipse-to-work-with-cakephp/" target="_blank">بیشتر راجع به مقدمات Eclipse در الوان‌وب</a></p>
<p><strong>پ‌ن</strong> : این نیمچه مقاله رو با الهام و ادقام <a href="http://www.smashingmagazine.com/2009/02/11/the-big-php-ides-test-why-use-oneand-which-to-choose/" target="_blank">این نوشته از مجله Smashing</a> و مطلبی در <a href="http://trac.symfony-project.org/wiki" target="_blank">ویکی symfony</a> نوشتم.</p>
<img src="http://www.moshtaghi.ir/weblog/?ak_action=api_record_view&id=389&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.moshtaghi.ir/2009/06/best-php-ide-and-compatible-with-symfony/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>آموزش سیمفونی روز پنجم – مسیر‌یابی</title>
		<link>http://weblog.moshtaghi.ir/2009/06/5th-symfony-jobeet/</link>
		<comments>http://weblog.moshtaghi.ir/2009/06/5th-symfony-jobeet/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 17:19:19 +0000</pubDate>
		<dc:creator>مهدی</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[routing]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.moshtaghi.ir/weblog/?p=379</guid>
		<description><![CDATA[اگر روز چهارم را تمام کرده باشید، باید به اصول MVC آشنا شده باشید. پس زمان بیشتری را صرف آن کنید و به گذشته فکر نکنید!
در تمرین دیروز، صفحات jobeet را گسترش دادیم، بنابراین چندین راه‌کار Symfony را بررسی کردیم. راه‌کارهایی همچون layout، کمک‌کننده‌ها و شیار‌ها.
امروز هم با دنیای شگفت انگیز مسیر‌یابی (Routing) در Symfony ]]></description>
			<content:encoded><![CDATA[<p>اگر روز چهارم را تمام کرده باشید، باید به اصول MVC آشنا شده باشید. پس زمان بیشتری را صرف آن کنید و به گذشته فکر نکنید!<br />
در تمرین دیروز، صفحات jobeet را گسترش دادیم، بنابراین چندین راه‌کار Symfony را بررسی کردیم. راه‌کارهایی همچون layout، کمک‌کننده‌ها و شیار‌ها.<br />
امروز هم با دنیای شگفت انگیز مسیر‌یابی (Routing) در Symfony آشنا می‌شویم.</p>
<h3>URLها</h3>
<p>اگر در صفحه اصلی بروی شغلی کلیک کنید، URL آن همانند این است: job/show/if/1 . اگر پیش از این وبسایتی را با PHP توسعه داده باشید، احتمالاْ بیشتر با URLهایی از قبیل job.php?id=1 خو گرفته‌اید. Symfony چگونه اینکار را انجام داد؟ چگونه اکشن مبنا برای URL را تعیین می‌کند؟ امروز پاسخ تمام این سوالات را بررسی می‌کنیم.<br />
اما ابتدا در رابطه با URLها صحبت می‌کنیم و اینکه آنها واقعاْ چه هستند. در مفاهیم وب، یک URL معرف یکتا برای وسیله‌ای در وب می‌باشد. هنگامی که به URL خاصی می‌روید، بوسیله همان URL از مرورگر برای واکشی وسیله‌ای معین سوال می‌کنید. بنابراین URL رابط میان وبسایت و کاربران است، که باید شامل اطلاعاتی از منبع خود باشد. اما URLهای مرسوم واقعاْ شرح درستی از محتوا نیستند، بلکه ساختار کلی برنامه را نمایش می‌دهند. کاربران به اینکه وبسایت شما بوسیله PHP توسعه داده‌شده و یا &#8230; کاری ندارند و از آن گذشته نشان دادن ساختار کاری برنامه به کاربران از لحاظ امنیتی کار اشتباهی می‌باشد. چرا که کاربران می‌توانند URL قسمت‌هایی که دسترسی محدود دارند را حدس بزنند. البته توسعه دهنده باید این صفحات را با شیوه مناسبی امن کند اما اینگونه شما می‌توانید بر امنیت آنها بیفزائید.<span id="more-379"></span><br />
URLها در Symfony به اندازه‌ای اهمیت دارند که فریم‌ورکی مختص به مدیریت آنها وجود دارد: فریم‌ورک مسیر‌یابی(routing). مسیر یابی URIهای داخلی و URLهای خارجی را مدیریت می‌کند. هنگامی که درخواستی وارد می‌شود، مسیر‌یاب URL را تجزیه کرده و به یک URI داخلی تبدیل می‌کند.<br />
شما قبلاْ URI داخلی صفحات job را در قالب showSuccess.php دیده‌اید:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">'job<span style="color: #66cc66;">/</span>show?id='.$job-<span style="color: #66cc66;">&gt;</span>getId<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>کمک‌کننده url_for() این URI داخلی را به یک URL صحیح تبدیل می‌کند:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>show<span style="color: #66cc66;">/</span>id<span style="color: #66cc66;">/</span><span style="color: #cc66cc;">1</span></pre></div></div>

<p>URIهای داخلی از چندین بخش تشکیل شده‌اند: job یک ماژول است، show یک اکشن است و رشته کوئری (query string) پارامتر‌هایی را برای اجرای اکشن اضافه می‌کند. طرح کلی برای URLها اینگونه است:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">MODULE<span style="color: #66cc66;">/</span>ACTION?key=value<span style="color: #66cc66;">&amp;</span>key_1=value_1<span style="color: #66cc66;">&amp;</span>...</pre></div></div>

<p>از آنجایی که Symfony دو راه برای پردازش دارد، می‌توانید URLها را بدون انجام کار تکنیکی تغییر دهید. این یکی از مزایای اصلی الگوی طراحی front-controller است.</p>
<h3>پیکره‌بندی مسیر‌یابی</h3>
<p>مسیر‌یابی بین URIها و URLها در فایل پیکره‌بندی routing.yml صورت می‌گیرد:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># apps/frontend/config/routing.yml</span>
homepage:
  <span style="color: #000066;">url</span>:   <span style="color: #66cc66;">/</span>
  param: <span style="color: #66cc66;">&#123;</span> module: default, action: index <span style="color: #66cc66;">&#125;</span>
&nbsp;
default_index:
  <span style="color: #000066;">url</span>:   <span style="color: #66cc66;">/</span>:module
  param: <span style="color: #66cc66;">&#123;</span> action: index <span style="color: #66cc66;">&#125;</span>
&nbsp;
default:
  <span style="color: #000066;">url</span>:   <span style="color: #66cc66;">/</span>:module<span style="color: #66cc66;">/</span>:action<span style="color: #808080; font-style: italic;">/*</span></pre></div></div>

<p>این فایل مسیر یابی را شرح می‌دهد. مسیر یک نام (homepage)، یک الگو (/:module/:action/*) و مقداری پارامتر دارد (کلید param). هنگامی که درخواستی وارد می‌شود، مسیر‌یاب سعی می‌کند تا URL را با یک الگو تطبیق دهد. اولین مسیر مصابقت داده‌شده انتخاب می‌شود، بنابراین ترتیب در routing.yml مهم است. به مثالی توجه کنید تا درک بهتری از مسیر یابی داشته باشید.<br />
هنگامی که شما صفحه‌اصلی jobeet را درخواست می‌کنید، که URL آن /job است، اولین مسیری که مطابقت دارد همان default_index است. در یک الگو، کلماتی که با پیشوند (:) می‌آیند متغیر هستند. بنابراین الگوی /:module به این معنی است که / را با هرچیزی به دنبال آن مطابقت دهد. در مثال ما، متغیر module مقدار job را دارد. این مقدار با کد زیر می‌تواند در اکشن بازیابی شود:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'module'</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>همچنین این مسیر‌یابی مقداری پیشفرض برای متغیر اکشن تعیین می‌کند. پس برای تمام URLهایی که با این مسیریاب مطابقت دارند، درخواست می‌تواند یک پارامتر action با مقدار index داشته باشد.<br />
اگر شما درخواست صفحه job/show/id/1 را بدهید، Symfony آن را با الگوی بعدی مطابقت می‌دهد: :module/:action/* . در یک الگو (*) با مجموعه‌ای از متغیر/مقدار که بوسیله / از هم جدا شده‌اند مطابقت دارد.</p>
<table class="doc_table" border="0" cellspacing="0">
<thead>
<tr>
<th>Request parameter</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>module</td>
<td>job</td>
</tr>
<tr>
<td>action</td>
<td>show</td>
</tr>
<tr>
<td>id</td>
<td>1</td>
</tr>
</tbody>
</table>
<blockquote><p><strong>یادداشت</strong>: متغیر‌های module و action خاص هستند جون بوسیله Symfony برای تصمیم در رابطه با اجرای اکشن استفاده می‌شوند.</p></blockquote>
<p>URL (آدرس) job/show/id/1 می‌تواند با استفاده از فراخوانی کمک‌کننده url_for() برای یک قالب ساخته شود:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">url_for<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'job/show?id='</span><span style="color: #339933;">.</span><span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>همچنین شما می‌توانید نام مسیرتان را با پیشوند @ مشخص کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">url_for<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@default?module=job&amp;action=show&amp;id='</span><span style="color: #339933;">.</span><span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>هر دو فراخوانی با هم مطابقت می‌کنند. اما دومی سریعتر است، زیرا مجبور به آزمایش تمامی مسیر‌یاب‌ها برای مطابقت بهتر نیست و برای پیاده‌سازی کمتر تلاش می‌کند. (نام ماژول و اکشن در URI داخلی حاضر نیستند).</p>
<h3>سازش مسیر &#8211; Route Customazation</h3>
<p>در حال‌حاضر، هنگامی که در‌خواست URL اسلش (/) را می‌دهید با صفحه خوش‌آمد سیمفونی مواجه می‌شوید. دلیل آن مطابقت URL با مسیر homepage است. اما می‌شود آن را به نفع خود تغییر داد. برای اینکار، متغیر module مسیر homepage را به job تغییر می‌دهیم.</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># apps/frontend/config/routing.yml</span>
homepage:
  <span style="color: #000066;">url</span>:   <span style="color: #66cc66;">/</span>
  param: <span style="color: #66cc66;">&#123;</span> module: job, action: index <span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>حال می‌توانیم پیوند موجود در لوگوی jobeet را در layout با استفاده از مسیر homepage تغییر دهیم.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt;!-- apps/frontend/templates/layout.php --&gt;
&lt;h1&gt;
  &lt;a href=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> url_for<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'@homepage'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;
    &lt;img src=&quot;/images/jobeet.gif&quot; alt=&quot;Jobeet Job Board&quot; /&gt;
  &lt;/a&gt;
&lt;/h1&gt;</pre></div></div>

<p>خیلی راحت بود. به عنوان یک کار پیچیده‌تر، تغییراتی را برای job ایجاد کنید تا URL پر معنی‌تری داشته باشد:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>rayan-pardaz<span style="color: #66cc66;">/</span>gorgan-iran<span style="color: #66cc66;">/</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">/</span>web-developer</pre></div></div>

<p>بدون دانستن هیچ اطلاعی راجع به jobeet و بدون حتی نگاه کردن به صفحه، می‌توان فهمید که شرکت رایان‌پرداز بدنبال یک توسعه دهنده وب برای کار کردن در گرگان-ایران می‌باشد!</p>
<blockquote><p><strong>یادداشت</strong>: برای رساندن اطلاعات به کاربران URLها بسیار مهم هستند. برای مثال زمانی که URL را در پست الکترونیکی کپی می‌کنید و یا وبسایت را برای موتور‌های جستجو بهینه می‌کنید.</p></blockquote>
<p>طرح زیر با اینچنین URLهایی مطابقت دارد:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>:company<span style="color: #66cc66;">/</span>:location<span style="color: #66cc66;">/</span>:id<span style="color: #66cc66;">/</span>:position</pre></div></div>

<p>فایل routing.yml را ویرایش کرده و مسیر job_show_user را در ابتدای آن اضافه کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">job_show_user:
  <span style="color: #000066;">url</span>:   <span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>:company<span style="color: #66cc66;">/</span>:location<span style="color: #66cc66;">/</span>:id<span style="color: #66cc66;">/</span>:position
  param: <span style="color: #66cc66;">&#123;</span> module: job, action: show <span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>اگر صفحه اصلی jobeet را refresh کنید، لینک مضاغل تغییری نکرده است و بدین خاطر است که برای ایجاد مسیر، شما باید تمامی متغیر‌های لازم را عبور دهید. پس فراخوانی url_for را در فایل indexSuccess.php تغییر دهید.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">url_for<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'job/show?id='</span><span style="color: #339933;">.</span><span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&amp;company='</span><span style="color: #339933;">.</span><span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCompany</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span>
  <span style="color: #0000ff;">'&amp;location='</span><span style="color: #339933;">.</span><span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLocation</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&amp;position='</span><span style="color: #339933;">.</span><span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPosition</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>همچنین یک URI داخلی می‌تواند بیان‌گر یک آرایه باشد.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">url_for<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
  <span style="color: #0000ff;">'module'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'job'</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'action'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'show'</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'id'</span>       <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'company'</span>  <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCompany</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'location'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLocation</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'position'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPosition</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<h3>احتیاجات</h3>
<p>روز اول آموزش درباره معتبرسازی و مدیریت خطاها برای دلایل درست بحث کردیم. سیستم مسیر‌یابی در ویژگی‌های معتبر سازی ایجاد شده است. هر متغیر الگو می‌تواند بوسیله یک عبارت تعیین شده که بوسیله requirements تعریف شده است، اعتبار سنجی شود:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">job_show_user:
  <span style="color: #000066;">url</span>:   <span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>:company<span style="color: #66cc66;">/</span>:location<span style="color: #66cc66;">/</span>:id<span style="color: #66cc66;">/</span>:position
  param: <span style="color: #66cc66;">&#123;</span> module: job, action: show <span style="color: #66cc66;">&#125;</span>
  requirements:
    id: \d+</pre></div></div>

<p>requirements ذکر شده در بالا، عددی بودن id را ضروری می‌کند و در غیر این صورت مسیر تطبیق داده نمی‌شود.</p>
<h3>کلاس مسیر</h3>
<p>در حقیقت هر یک از تعاریف موجود در فایل routing.yml به یک شیء از کلاس sfroute تبدیل می‌شود. این کلاس‌ها می‌توانند بوسیله تعریف یک مشخصه کلاس در تعاریف مسیر تغییر کنند. اگر شما با پروتوکل http آشنا باشید، می‌دانید که متد‌های زیادی همچون GET، POST، HEA D، DELETE و PUT را تعریف می‌کند. سه‌تای اول در تمام مرورگر‌ها پشتیبانی می‌شوند و دو‌تای دیگر نه.<br />
برای محدود کردن تطابق مسیر به برخی از متد‌های درخواست، می‌توانید کلاس مسیر را به sfRequestRoute تغییر داده و الزامی را برای متغیر مجازی sf_method اضافه کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">job_show_user:
  <span style="color: #000066;">url</span>:   <span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>:company<span style="color: #66cc66;">/</span>:location<span style="color: #66cc66;">/</span>:id<span style="color: #66cc66;">/</span>:position
  class: sfRequestRoute
  param: <span style="color: #66cc66;">&#123;</span> module: job, action: show <span style="color: #66cc66;">&#125;</span>
  requirements:
    id: \d+
    sf_method: <span style="color: #66cc66;">&#91;</span>get<span style="color: #66cc66;">&#93;</span></pre></div></div>

<blockquote><p><strong>یادداشت</strong>: ملزوم کردن مسیر برای مطابقت با برخی از متد‌های http کاملاْ با استفاده ازsfWebRequest::isMethod() در اکشن برابری نمی‌کند، به این دلیل که مسیر‌یابی در صورت عدم تطابق به دنبال مسیر دیگری برای تطابق می‌گردد.</p></blockquote>
<h3>کلاس شیء مسیر &#8211; Object Route Class</h3>
<p>URI جدید یک شغل واقعاْ طولانی و نوشتن ان سخت است (url_for(&#8217;job/show?id=&#8217;.$job->getId().&#8217;&#038;company=&#8217;.$job->getCompany().&#8217;&#038;location=&#8217;.$job->getLocation().&#8217;&#038;position=&#8217;.$job->getPosition())) اما در قسمت قبل یاد گرفتیم که کلاس مسیر می‌تواند تغییر کند. برای مسیر job_show_user بهتر است که از sfPropelRoute استفاده کنیم. چون این کلاس برای مسیر‌هایی که اشیاء propel یا کلکسیونی از آنها را نمایش می‌دهند بهینه شده است.</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">job_show_user:
  <span style="color: #000066;">url</span>:     <span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>:company<span style="color: #66cc66;">/</span>:location<span style="color: #66cc66;">/</span>:id<span style="color: #66cc66;">/</span>:position
  class:   sfPropelRoute
  options: <span style="color: #66cc66;">&#123;</span> model: JobeetJob, <span style="color: #000000; font-weight: bold;">type</span>: <span style="color: #000066;">object</span> <span style="color: #66cc66;">&#125;</span>
  param:   <span style="color: #66cc66;">&#123;</span> module: job, action: show <span style="color: #66cc66;">&#125;</span>
  requirements:
    id: \d+
    sf_method: <span style="color: #66cc66;">&#91;</span>get<span style="color: #66cc66;">&#93;</span></pre></div></div>

<p>مقدار مشخص شده برای options رفتار مسیر را بهینه می‌کند. در اینجا خصیصه model کلاس مدل کلاس مدل پروپل (JobeetJob) وابسته به مسیر را مشخص می‌کند، و خصیصه type هم تعیین می‌کند که این مسیر باید یک شیء را نشان دهد. (همچنین برای نمایشش کلکسیونی از اشیاء می‌توان از list استفاده کرد)<br />
حالا مسیر job_show_user متوجه شده است که با JobeetJob رابطه دارد و بنابراین براحتی با url_for فراخوانی می‌شود:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">url_for<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sf_route'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'job_show_user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'sf_subject'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$job</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>و یا تنها:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">url_for<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'job_show_user'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$job</span><span style="color: #009900;">&#41;</span></pre></div></div>

<blockquote><p><strong>یادداشت</strong>: مثال اول برای زمانی که احتیاج به عبور آرگومنت‌های زیادی برای یک شیء است می‌تواند بسیار سودمند باشد.</p></blockquote>
<p>چون تمام متغیر‌ها در این مسیر یک مقدار نظیر به نظیر قابل دستیابی در کلاس JobeetJob دارند، بخوبی کار می‌کند. (برای مثال، متغیر company با مقدار getCompany() جایگزین می‌شود)<br />
اگر به URLهای ساخته شده نگاه کنید، خواهید دید که کاملا به چیزی که می‌خواهیم تبدیل نشده است.</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">http:<span style="color: #808080; font-style: italic;">//jobeet.localhost/frontend_dev.php/job/Sensio+Labs/Paris%2C+France/1/Web+Developer</span></pre></div></div>

<p>نیاز داریم تا مقادیر ستون‌ها را بصورت slug در آوریم. فایل JobeetJob را باط کرده و متد زیر را به آن اضافه کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/model/JobeetJob.php</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getCompanySlug<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">return</span> Jobeet<span style="color: #339933;">::</span><span style="color: #004000;">slugify</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCompany</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getPositionSlug<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">return</span> Jobeet<span style="color: #339933;">::</span><span style="color: #004000;">slugify</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPosition</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getLocationSlug<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">return</span> Jobeet<span style="color: #339933;">::</span><span style="color: #004000;">slugify</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLocation</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>سپس فایل lib/Jobeet.class.php را ایجاد کرده و متد slugify را در آن اضافه کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/Jobeet.class.php</span>
<span style="color: #000000; font-weight: bold;">class</span> Jobeet
<span style="color: #009900;">&#123;</span>
  static <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> slugify<span style="color: #009900;">&#40;</span><span style="color: #000088;">$text</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// replace all non letters or digits by -</span>
    <span style="color: #000088;">$text</span> <span style="color: #339933;">=</span> <span style="color: #990000;">preg_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/\W+/'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'-'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$text</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// trim and lowercase</span>
    <span style="color: #000088;">$text</span> <span style="color: #339933;">=</span> <span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$text</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'-'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$text</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>حالا سه تا دسترسی مجازی داریم:<br />
getCompanySlug()، getPositionSlug() و getLocationSlug(). اینها مقادیر این سه ستون را در قالب متد slugify بر‌میگردانند. حالا می‌توانید نام اصلی ستون‌ها را با مشابه slug شده انها در مسیر job_show_user تغییر دهید:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">job_show_user:
  <span style="color: #000066;">url</span>:     <span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>:company_slug<span style="color: #66cc66;">/</span>:location_slug<span style="color: #66cc66;">/</span>:id<span style="color: #66cc66;">/</span>:position_slug
  class:   sfPropelRoute
  options: <span style="color: #66cc66;">&#123;</span> model: JobeetJob, <span style="color: #000000; font-weight: bold;">type</span>: <span style="color: #000066;">object</span> <span style="color: #66cc66;">&#125;</span>
  param:   <span style="color: #66cc66;">&#123;</span> module: job, action: show <span style="color: #66cc66;">&#125;</span>
  requirements:
    id: \d+
    sf_method: <span style="color: #66cc66;">&#91;</span>get<span style="color: #66cc66;">&#93;</span></pre></div></div>

<p>از آنجایی که کلاسی به سیستم اضافه شده است، قبل از refresh کردن صفحه اصلی لازم است تا cach را پاک کنید.</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">$ php symfony cc</pre></div></div>

<p>حالا می‌توانید URLها را اینگونه مشاهده کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">http:<span style="color: #808080; font-style: italic;">//jobeet.localhost/frontend_dev.php/job/sensio-labs/paris-france/1/web-developer</span></pre></div></div>

<p>اما این تنها نصف داستان است. مسیر قابلیت آن را دارد که بر مبنای یک شیء ایجاد شود، اما در عین حال قابلیت پیدا کردن شیء مرتبط به URL معین را هم دارد. شیء مرتبط می‌تواند با متد getObject() از شیء مسیر بازیافت شود. هنگامی که یک در‌خواست ورودی تجزیه می‌شود ذخائر مسیر‌یابی شیء مسیر را برای استفاده شیء در اکشن‌ها تطبیق می‌دهند. بنابراین متد executeShow() را برای استفاده شیء مسیر برای بازگرداندن شیء jobeet تغییر دهید:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> jobActions <span style="color: #000000; font-weight: bold;">extends</span> sfActions
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeShow<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">job</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRoute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404Unless</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">job</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>اگر سعی کنید شغلی را با یک id ناشناخته دریافت کنید، صفحه ۴۰۴ را با اخطاری متفاوت می‌بینید:</p>
<div id="attachment_517" class="wp-caption aligncenter" style="width: 310px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/06/404_propel_route.png"><img class="size-medium wp-image-517" title="برای مشاهده ابعاد بزرگتر کلیک کنید" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/06/404_propel_route-300x103.png" alt="404_propel_route" width="300" height="103" /></a><p class="wp-caption-text">اخطار ۴۰۴ که توسط متد getRoute بوجود آمده است</p></div>
<p>این بدین خاطر است که اخطار ۴۰۴ بطور خودکار و بوسیله متد getRoute() پیش آمده. بنابراین می‌شود متد executeShow را ساده‌تر کرد:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> jobActions <span style="color: #000000; font-weight: bold;">extends</span> sfActions
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeShow<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">job</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRoute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<blockquote><p><strong>نکته</strong>: اگر نمی‌خواهید مسیر به صفحه ۴۰۴ منتقل شود، می‌توانید مقدار allow_empty را به true تغییر دهید.</p></blockquote>
<blockquote><p><strong>یادداشت</strong>: اشیا مرتبط یک مسیر بسیار تنبل هستند. و تنها در صورتی که شما متد getRoute() را فراخوانی کرده باشید، از پایگاه داده بازیافت می‌شوند.</p></blockquote>
<h3>مسیریابی در اکشن‌ها و قالب‌ها</h3>
<p>در قالب، کمک کننده url_for آدرس‌های داخلی را به URLهای خارجی تبدیل می‌کند. برخی از کمک‌کننده‌های دیگر سیمفونی URLهای داخلی را در قالب آرگومنت می‌گیرند، همچون کمک‌کننده link_to که یک تگ a ایجاد می‌کند:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> link_to<span style="color: #009900;">&#40;</span><span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPosition</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'job_show_user'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$job</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>خروجی این کد در قالب HTML اینچنین است:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;a href=&quot;/job/sensio-labs/paris-france/1/web-developer&quot;&gt;Web Developer&lt;/a&gt;</pre></div></div>

<p>هر دوی این کمک‌کننده‌ها می‌توانند URLهای مطلق ایجاد کنند:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">url_for<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'job_show_user'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$job</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
link_to<span style="color: #009900;">&#40;</span><span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPosition</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'job_show_user'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$job</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>اگر می‌خواهید یک URL از یک اکشن ایجاد کنید، می‌توانید از متد generateUrl() استفاده کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">generateUrl</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'job_show_user'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$job</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<blockquote>
<h4>خانواده متد‌های redirect</h4>
<p>در قسمت قبل این آموزش، در مورد متد‌های forward صحبت کردیم. این متد‌ها درخواست جاری را بدون رفت و برگشت مرورگر به یک اکشن دیگر ارسال می‌کرد.<br />
متد‌های redirect کاربر را به یک URL دیگر هدایت می‌کند. همچون forward می‌توانید از متد redirect()و یا متد های میانبر redirectIf() و redirectUnless() استفاده کنید.</p></blockquote>
<h3>مجموعه کلاس های مسیر</h3>
<p>قبلاْ برای ماژول job، مسیر اکشن show را بهینه کردیم. اما URL سایر متد‌ها ( همچون index و new و &#8230;) بوسیله مسیر پیشفرض مدیریت می‌شوند:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">default:
  <span style="color: #000066;">url</span>: <span style="color: #66cc66;">/</span>:module<span style="color: #66cc66;">/</span>:action<span style="color: #808080; font-style: italic;">/*</span></pre></div></div>

<p>مسیر default راه خوبی بای شروع کد‌نویسی بدون مشخص کردن تعداد زیادی مسیر می‌باشد. اما چون مسیر به یک catch-all اثر می‌کند، نمی‌تواند برای نیاز‌های خاص ما پیکره‌بندی شود.<br />
ار آنجایی که تمام اکشن‌های job با کلاس مدل JobeetJob مرتبط هستند، همانطور که قبلاْ برای اکشن show اینکار را انجام دادیم می‌توانیم براحتی یک مسیر دستی sfPropelRoute برای هر یک مشخص کنیم. اما همچون ماژول job مشخص کردن هفت اکشن کلاسیک برای یک مدل سخت است، گذشته از این می‌شود از کلاس sfPropelRouteCollection استفاده کرد. فایل routing.yml را باز کرده و تغییرات زیر را در ان اعمال کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># apps/frontend/config/routing.yml</span>
job:
  class:   sfPropelRouteCollection
  options: <span style="color: #66cc66;">&#123;</span> model: JobeetJob <span style="color: #66cc66;">&#125;</span>
&nbsp;
job_show_user:
  <span style="color: #000066;">url</span>:     <span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>:company_slug<span style="color: #66cc66;">/</span>:location_slug<span style="color: #66cc66;">/</span>:id<span style="color: #66cc66;">/</span>:position_slug
  class:   sfPropelRoute
  options: <span style="color: #66cc66;">&#123;</span> model: JobeetJob, <span style="color: #000000; font-weight: bold;">type</span>: <span style="color: #000066;">object</span> <span style="color: #66cc66;">&#125;</span>
  param:   <span style="color: #66cc66;">&#123;</span> module: job, action: show <span style="color: #66cc66;">&#125;</span>
  requirements:
    id: \d+
    sf_method: <span style="color: #66cc66;">&#91;</span>get<span style="color: #66cc66;">&#93;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># default rules</span>
homepage:
  <span style="color: #000066;">url</span>:   <span style="color: #66cc66;">/</span>
  param: <span style="color: #66cc66;">&#123;</span> module: job, action: index <span style="color: #66cc66;">&#125;</span>
&nbsp;
default_index:
  <span style="color: #000066;">url</span>:   <span style="color: #66cc66;">/</span>:module
  param: <span style="color: #66cc66;">&#123;</span> action: index <span style="color: #66cc66;">&#125;</span>
&nbsp;
default:
  <span style="color: #000066;">url</span>:   <span style="color: #66cc66;">/</span>:module<span style="color: #66cc66;">/</span>:action<span style="color: #808080; font-style: italic;">/*</span></pre></div></div>

<p>مسیر job در بالا می‌تواند یک میانبر به هفت مسیر زیر را بطور خودکار ایجاد کند:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">job:
  <span style="color: #000066;">url</span>:     <span style="color: #66cc66;">/</span>job.:sf_format
  class:   sfPropelRoute
  options: <span style="color: #66cc66;">&#123;</span> model: JobeetJob, <span style="color: #000000; font-weight: bold;">type</span>: <span style="color: #000000; font-weight: bold;">list</span> <span style="color: #66cc66;">&#125;</span>
  param:   <span style="color: #66cc66;">&#123;</span> module: job, action: index, sf_format: html <span style="color: #66cc66;">&#125;</span>
  requirements: <span style="color: #66cc66;">&#123;</span> sf_method: get <span style="color: #66cc66;">&#125;</span>
&nbsp;
job_new:
  <span style="color: #000066;">url</span>:     <span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>new.:sf_format
  class:   sfPropelRoute
  options: <span style="color: #66cc66;">&#123;</span> model: JobeetJob, <span style="color: #000000; font-weight: bold;">type</span>: <span style="color: #000066;">object</span> <span style="color: #66cc66;">&#125;</span>
  param:   <span style="color: #66cc66;">&#123;</span> module: job, action: new, sf_format: html <span style="color: #66cc66;">&#125;</span>
  requirements: <span style="color: #66cc66;">&#123;</span> sf_method: get <span style="color: #66cc66;">&#125;</span>
&nbsp;
job_create:
  <span style="color: #000066;">url</span>:     <span style="color: #66cc66;">/</span>job.:sf_format
  class:   sfPropelRoute
  options: <span style="color: #66cc66;">&#123;</span> model: JobeetJob, <span style="color: #000000; font-weight: bold;">type</span>: <span style="color: #000066;">object</span> <span style="color: #66cc66;">&#125;</span>
  param:   <span style="color: #66cc66;">&#123;</span> module: job, action: create, sf_format: html <span style="color: #66cc66;">&#125;</span>
  requirements: <span style="color: #66cc66;">&#123;</span> sf_method: post <span style="color: #66cc66;">&#125;</span>
&nbsp;
job_edit:
  <span style="color: #000066;">url</span>:     <span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>:id<span style="color: #66cc66;">/</span>edit.:sf_format
  class:   sfPropelRoute
  options: <span style="color: #66cc66;">&#123;</span> model: JobeetJob, <span style="color: #000000; font-weight: bold;">type</span>: <span style="color: #000066;">object</span> <span style="color: #66cc66;">&#125;</span>
  param:   <span style="color: #66cc66;">&#123;</span> module: job, action: edit, sf_format: html <span style="color: #66cc66;">&#125;</span>
  requirements: <span style="color: #66cc66;">&#123;</span> sf_method: get <span style="color: #66cc66;">&#125;</span>
&nbsp;
job_update:
  <span style="color: #000066;">url</span>:     <span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>:id.:sf_format
  class:   sfPropelRoute
  options: <span style="color: #66cc66;">&#123;</span> model: JobeetJob, <span style="color: #000000; font-weight: bold;">type</span>: <span style="color: #000066;">object</span> <span style="color: #66cc66;">&#125;</span>
  param:   <span style="color: #66cc66;">&#123;</span> module: job, action: update, sf_format: html <span style="color: #66cc66;">&#125;</span>
  requirements: <span style="color: #66cc66;">&#123;</span> sf_method: put <span style="color: #66cc66;">&#125;</span>
&nbsp;
job_delete:
  <span style="color: #000066;">url</span>:     <span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>:id.:sf_format
  class:   sfPropelRoute
  options: <span style="color: #66cc66;">&#123;</span> model: JobeetJob, <span style="color: #000000; font-weight: bold;">type</span>: <span style="color: #000066;">object</span> <span style="color: #66cc66;">&#125;</span>
  param:   <span style="color: #66cc66;">&#123;</span> module: job, action: delete, sf_format: html <span style="color: #66cc66;">&#125;</span>
  requirements: <span style="color: #66cc66;">&#123;</span> sf_method: delete <span style="color: #66cc66;">&#125;</span>
&nbsp;
job_show:
  <span style="color: #000066;">url</span>:     <span style="color: #66cc66;">/</span>job<span style="color: #66cc66;">/</span>:id.:sf_format
  class:   sfPropelRoute
  options: <span style="color: #66cc66;">&#123;</span> model: JobeetJob, <span style="color: #000000; font-weight: bold;">type</span>: <span style="color: #000066;">object</span> <span style="color: #66cc66;">&#125;</span>
  param:   <span style="color: #66cc66;">&#123;</span> module: job, action: show, sf_format: html <span style="color: #66cc66;">&#125;</span>
  requirements: <span style="color: #66cc66;">&#123;</span> sf_method: get <span style="color: #66cc66;">&#125;</span></pre></div></div>

<blockquote><p><strong>یادداشت</strong>: برخی از مسیر‌هایی که بوسیله  sfPropelRouteCollection ایجاد شده‌اند، URLهای یکسان دارند. مسیریاب باز هم قابلیت استفاده از انها را دارد زیرا هرکدام نیاازمند یک متد خاص http هستند.</p></blockquote>
<p>مسیر‌های job_delete و job_update متد‌هایی را نیاز دارند که توسط مرورگر پشتیبانی نمی‌شود، اما به این دلیل که Symfony آن را شبیه‌سازی می‌کند بدرستی کار می‌کنند. قالب _form.php را باز کنید تا یک مثال را مشاهده کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">// apps/frontend/modules/job/templates/_form.php
&lt;form action=&quot;...&quot; ...&gt;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">isNew</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  &lt;input type=&quot;hidden&quot; name=&quot;sf_method&quot; value=&quot;PUT&quot; /&gt;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> link_to<span style="color: #009900;">&#40;</span>
  <span style="color: #0000ff;">'Delete'</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'job/delete?id='</span><span style="color: #339933;">.</span><span style="color: #000088;">$form</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getObject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
  <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'method'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'delete'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'confirm'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Are you sure?'</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>تمام کمک‌کننده‌های symfony می‌توانند شبیه‌سازی یک هر متد http را که باید به یک پارامتر خاص sf_method عبور داده‌شوند را بیان کنند.</p>
<blockquote><p><strong>یادداشت</strong>: سیمفونی پارامتر‌های خاص دیگری را همچون sf_method را هم دارد که همه با پیشوند sf_ شروع می‌شوند.<br />
در مسیر‌های ساخته شده در بالا می‌توانید بقیه را مشاهده کنید، sf_format که هر یک در آینده توضیح داده خواهند شد.</p></blockquote>
<h3>اشکال‌زدایی مسیر</h3>
<p>هنگامی که از مجموعه‌ی مسیر استفاده می‌کنید، بد نیست تا بعضی اوقات مسیر‌های ساخته شده را لیست کنیم. خروجی دستور app:routes تمام مسیر‌ها را برای application دریافتی می‌دهد:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">$ php symfony app:routes frontend</pre></div></div>

<p>همچنین می‌شود اطلاعات زیادی را برای اشکال‌زدایی مسیر بوسیله رد کردن نام آن در قالب یک آرگومنت داشته باشید:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">$ php symfony app:routes frontend job_edit</pre></div></div>

<h3>مسیر‌های پیشفرض</h3>
<p>مشخص کردن مسیر‌های مختلف برای تمامی URLها تمرین خوبی بود، همچون مسیر job که تمامی مسیر‌های لازم برای شرح دادن jobeet را مشخص می‌کرد.<br />
مسیر‌های پیشفرض در فایل routing.yml را پاک کرده یا کامنت کنید.</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># apps/frontend/config/routing.yml</span>
<span style="color: #808080; font-style: italic;">#default_index:</span>
<span style="color: #808080; font-style: italic;">#  url:   /:module</span>
<span style="color: #808080; font-style: italic;">#  param: { action: index }</span>
<span style="color: #808080; font-style: italic;">#</span>
<span style="color: #808080; font-style: italic;">#default:</span>
<span style="color: #808080; font-style: italic;">#  url:   /:module/:action/*</span></pre></div></div>

<p>برنامه همچون قبل بخوبی کار می‌کند.</p>
<h3>فردا می‌بینمتون</h3>
<p>امروز اطلاعات جدید زیادی را دریافت کردیم. یاد گرفتیم که چگونه از فریم‌ورک مسیر‌یابی symfony استفاده کنیم و چگونه بوسیله آن URLها را از ساختار تکنیکی برنامه جدا کنیم.<br />
فردا مفاهیم جدیدی را معرفی می‌کنیم.<br />
پ‌ن &#8211; شما لطفاْ در صورت برخوردن با هر مشکلی در زمینه این آموزش شرح کامل رو اینجا بگذارید تا شاید بکار سایر کاربرا هم بیاد. ممنون</p>
<img src="http://www.moshtaghi.ir/weblog/?ak_action=api_record_view&id=379&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.moshtaghi.ir/2009/06/5th-symfony-jobeet/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>آموزش سیمفونی روز چهارم – کنترل کننده‌ها و نما‌ها</title>
		<link>http://weblog.moshtaghi.ir/2009/05/4th-symfony-jobeet/</link>
		<comments>http://weblog.moshtaghi.ir/2009/05/4th-symfony-jobeet/#comments</comments>
		<pubDate>Sun, 24 May 2009 15:50:34 +0000</pubDate>
		<dc:creator>مهدی</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[layout]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[request]]></category>
		<category><![CDATA[response]]></category>
		<category><![CDATA[slot]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.moshtaghi.ir/weblog/?p=366</guid>
		<description><![CDATA[در قسمت قبل دیدید که سیمفونی چگونه بوسیله کم کردن تفاوت‌های بین موتور‌های پایگاه داده و تبدیل عناصر رابطه‌ای به کلاس‌های رابطه‌ای اشیاء، مدیریت پایگاه داده را ساده می‌کند.
امروز قصد داریم تا ماژول job که دیروز ایجاد کردیم را توسعه دهیم. تمام چیزی که مورد نیاز است اینجا لیست شده است:

 صفحه‌ای برای لیست کردن ]]></description>
			<content:encoded><![CDATA[<p>در قسمت قبل دیدید که سیمفونی چگونه بوسیله کم کردن تفاوت‌های بین موتور‌های پایگاه داده و تبدیل عناصر رابطه‌ای به کلاس‌های رابطه‌ای اشیاء، مدیریت پایگاه داده را ساده می‌کند.<br />
امروز قصد داریم تا ماژول job که دیروز ایجاد کردیم را توسعه دهیم. تمام چیزی که مورد نیاز است اینجا لیست شده است:</p>
<ul>
<li> صفحه‌ای برای لیست کردن مشاغل</li>
<li> صفحه‌ای برای ایجاد شغل جدید</li>
<li> صفحه‌ای برای ویرایش مشاغل موجود</li>
<li> صفحه‌ای برای حذف مشاغل</li>
</ul>
<p>اگرچه کدها برای استفاده حاضر هستند، اما نیاز است تا با بررسی مجدد، قالب‌ها را برای نزدیکی بیشتر Jobeet بهینه کنیم.<span id="more-366"></span></p>
<h3>ساختار Model View Controllers &#8211; MVC</h3>
<p>اگر شما تا کنون برای توسعه وب از فریم‌ورکی استفاده نکرده‌اید، احتمالاْ کدهای PHP خود را در قالب صفحات HTML می‌نوشتید.<br />
احتمالاْ شیوه کار این فایل‌ها اینگونه بود: ارزش دهی و پیکره‌بندی کلی، منطق برنامه و رابطه ان با صفحات، بازیابی رکورد‌های پایگاه داده و در نهایت کدهای HTMLی که صفحه را پدید می‌آورند.<br />
ایجاد تغییرات در چنین ساختاری، مخصوصاْ پس از گذشت مدتی بسیار سخت و طاقت فرسا است. و بدتر از آن زمانی است که شخص دیگری قصد ویرایش این کدها را داشته باشد.(کار گروهی)<br />
اما این مشکل راه حل بسیار خوبی دارد.<br />
رایج‌ترین ساختار برای مرتب سازی کدها در طراحی وب <a title="MVC در ویکی‌پدیای انگلیسی" href="http://en.wikipedia.org/wiki/Model-view-controller" target="_blank">الگوی طراحی MVC</a> است. بطور خلاصه، MVC راهی را برای مرتب سازی کد‌های شما با طبیعت خودش، مشخص می‌کند. این الگو کد‌ها را به سه لایه مجزا تقسیم می‌کند:<br />
<strong>لایه مدل</strong>: منطق برنامه را مشخص می کند، سیمفونی نیز تمام فایل‌های مربوط به این لایه را در lib/model ذخیره می‌کند.<br />
<strong>لایه نما</strong>: چگونگی نمایش است، (موتور قالب قسمتی از این لایه است) در سیمفونی لایه View بیشتر از کد‌های PHP ساخته می‌شود و در پوشه‌های مختلف template ذخیره می‌شود و در ادامه همین قسمت به آنها خواهیم پرداخت.<br />
<strong>لایه کنترل کننده</strong>: قسمتی از کد‌ها که وظیفه فراخوانی Model را برای داده‌های عبور داده شده از لایه View را برای رندر شدن کلاینت را برعهده دارد.</p>
<div id="attachment_431" class="wp-caption aligncenter" style="width: 310px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/mvc.png"><img class="size-medium wp-image-431" title="برای مشاهده ابعاد بزرگتر کلیک کنید" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/mvc-300x240.png" alt="چگونگی عملکرد ساختار MVC" width="300" height="240" /></a><p class="wp-caption-text">چگونگی عملکرد ساختار MVC</p></div>
<p>هنگامی که در قسمت اول سیمفونی را نصب کردیم، دیدید که چگونه درخواست‌ها بوسیله front controllers مدیریت می‌شدند (index.php and frontend_dev.php).همین front controllers کار اصلی را انجام می‌دهند.<br />
همانطور که دیروز هم دیدید، این عملیات منطقاْ در ماژول‌ها دسته بندی شده‌اند.<br />
امروز با استفاده از مدل آزمایشی مطرح شده در روز دوم، صفحه اصلی و صفحه شغل را تغییر می‌دهیم و انها را پویا می‌کنیم.<br />
در این راه موارد زیادی در فایل‌های مختلفی برای شرح ساختار پوشه‌های سیمفونی بکار می‌بریم و این کد‌ها را بین لایه‌ها تقسیم می‌کنیم.</p>
<h3>طرح بندی – Layout</h3>
<p>اگر به یک مدل نگاهی کنید، به شباهت اکثر این صفحات به هم پی می‌برید و همچنین می‌دانید که تکرار کد کار درستی نیست، چه کدهای HTML و چه PHP. بنابراین به راهی نیاز داریم تا از این کپی برداری‌ها جلوگیری شود.<br />
یک راه برای این مشکل مشخص کردن هیدر و فوتر و include کردن آنها در هر قالب است.</p>
<div id="attachment_441" class="wp-caption aligncenter" style="width: 310px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/header_footer.png"><img class="size-medium wp-image-441" title="برای مشاهده ابعاد بزرگتر کلیک کنید" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/header_footer-300x63.png" alt="header_footer" width="300" height="63" /></a><p class="wp-caption-text">ساختار Header - footer</p></div>
<p>اما در اینجا فایل‌های هیدر و فوتر شامل HTML معتبری نیستند. راه بهتری هم وجود دارد، بجای اینکار از یک الگوی طراحی دیگر استفاده می‌کنیم <a href="http://en.wikipedia.org/wiki/Decorator_pattern" target="_blank">الگوی طراحی آذین داخلی (decorator)</a>.<br />
این الگو برای حا این مشکل اینگونه عمل می‌کند:<br />
قالب پس از رندر محتوا بوسیله یک قالب سراسری آراسته می‌شود، فراخوان کردن یک <strong>layout</strong> در سیمفونی.</p>
<div id="attachment_444" class="wp-caption aligncenter" style="width: 310px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/layout.png"><img class="size-medium wp-image-444" title="برای مشاهده ابعاد واقعی کلیک کنید" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/layout-300x82.png" alt="برای مشاهده ابعاد واقعی کلیک کنید" width="300" height="82" /></a><p class="wp-caption-text">ساختار layout</p></div>
<p>Layout پیشفرض یک application فایل layout.php را فراخوانی می‌کند که آن را در مسیر apps/frontend/templates می‌بینید.<br />
این پوشه شامل تمامی قالب‌های سراسری برای application است. کد‌های زیر را با کد‌های موجود در layout.php عوض کنید.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt;!-- apps/frontend/templates/layout.php --&gt;
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;
 &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;title&gt;Jobeet - Your best job board&lt;/title&gt;
    &lt;link rel=&quot;shortcut icon&quot; href=&quot;/favicon.ico&quot; /&gt;
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> include_javascripts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> include_stylesheets<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;container&quot;&gt;
      &lt;div id=&quot;header&quot;&gt;
        &lt;div class=&quot;content&quot;&gt;
          &lt;h1&gt;&lt;a href=&quot;/job&quot;&gt;
            &lt;img src=&quot;/images/jobeet.gif&quot; alt=&quot;Jobeet Job Board&quot; /&gt;
          &lt;/a&gt;&lt;/h1&gt;
&nbsp;
          &lt;div id=&quot;sub_header&quot;&gt;
            &lt;div class=&quot;post&quot;&gt;
              &lt;h2&gt;Ask for people&lt;/h2&gt;
              &lt;div&gt;
                &lt;a href=&quot;/job/new&quot;&gt;Post a Job&lt;/a&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&nbsp;
            &lt;div class=&quot;search&quot;&gt;
              &lt;h2&gt;Ask for a job&lt;/h2&gt;
              &lt;form action=&quot;&quot; method=&quot;get&quot;&gt;
                &lt;input type=&quot;text&quot; name=&quot;keywords&quot;
                  id=&quot;search_keywords&quot; /&gt;
                &lt;input type=&quot;submit&quot; value=&quot;search&quot; /&gt;
                &lt;div class=&quot;help&quot;&gt;
                  Enter some keywords (city, country, position, ...)
                &lt;/div&gt;
              &lt;/form&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
&nbsp;
      &lt;div id=&quot;content&quot;&gt;
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sf_user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">hasFlash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'notice'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
          &lt;div class=&quot;flash_notice&quot;&gt;
            <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$sf_user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getFlash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'notice'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
          &lt;/div&gt;
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sf_user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">hasFlash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'error'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
          &lt;div class=&quot;flash_error&quot;&gt;
            <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$sf_user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getFlash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'error'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
          &lt;/div&gt;
        <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
        &lt;div class=&quot;content&quot;&gt;
          <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$sf_content</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
        &lt;/div&gt;
      &lt;/div&gt;
&nbsp;
      &lt;div id=&quot;footer&quot;&gt;
        &lt;div class=&quot;content&quot;&gt;
          &lt;span class=&quot;symfony&quot;&gt;
            &lt;img src=&quot;/images/jobeet-mini.png&quot; /&gt;
            powered by &lt;a href=&quot;http://www.symfony-project.org/&quot;&gt;
            &lt;img src=&quot;/images/symfony.gif&quot; alt=&quot;symfony framework&quot; /&gt;
            &lt;/a&gt;
          &lt;/span&gt;
          &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;&quot;&gt;About Jobeet&lt;/a&gt;&lt;/li&gt;
            &lt;li class=&quot;feed&quot;&gt;&lt;a href=&quot;&quot;&gt;Full feed&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;&quot;&gt;Jobeet API&lt;/a&gt;&lt;/li&gt;
            &lt;li class=&quot;last&quot;&gt;&lt;a href=&quot;&quot;&gt;Affiliates&lt;/a&gt;&lt;/li&gt;
          &lt;/ul&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre></div></div>

<p>یک قالب سیمفونی، تنها یک فایل ساده PHP است. در طرح‌بندی قالب می‌توانید فانکشن‌های PHP را فراخوانی کنید و به متغیر‌های PHP اشاره کنید. $sf_content متغیر جالبی است که بوسیله خود فریم‌ورک مشخص شده است و شامل کد‌های HTML ساخته شده توسط اکشن‌ها می‌باشد.<br />
اگر شما ماژول Job را مشاهده کنید (http://jobeet.localhost/frontend_dev.php/job)، خواهید دید که تمامی اکشن‌ها بوسیله این طرح آراسته شده‌اند.</p>
<h3>سبک‌نامه‌ها، تصاویر و جاوا اسکریپت‌ها – CSS, Images and Java Scripts</h3>
<p>این آموزش در مورد طراحی وب نیست بلکه در رابطه با توسعه آن است پس شما می‌توانید تمام موارد لازم برای این پروژه را از آدرس‌های زیر دریافت کنید.<br />
<a href="http://www.symfony-project.org/get/jobeet/images.zip">دریافت تصاویر</a> و ذخیره آنها در پوشه web/images<br />
<a href="http://www.symfony-project.org/get/jobeet/css.zip">دریافت سبک‌نامه‌ها</a> و ذخیره آنها در پوشه web/css</p>
<blockquote><p><strong>یادداشت</strong>: آیکن برنامه را هم می‌توانید از <a href="http://www.symfony-project.org/get/jobeet/favicon.ico">این ادرس</a> دریافت کنید و در پوشه web ذخیره کنید.</p></blockquote>
<div id="attachment_449" class="wp-caption aligncenter" style="width: 310px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/job_layout_assets.png"><img class="size-medium wp-image-449" title="برای مشاهده ابعاد بزرگتر کلیک کنید" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/job_layout_assets-300x253.png" alt="نام" width="300" height="253" /></a><p class="wp-caption-text">خروجی layout برنامه</p></div>
<blockquote><p><strong>نکته</strong>: در حالت پیشفرض دستور generate:project سه پوشه جهت ذخیره ملزومات پروژه ایجاد می‌کند: web/images برای تصاویر، web/css برای فایل‌های استایل و پوشه web/js برای فایل‌های جاوا اسکریپت.<br />
این ساختتار فقط یکی از قرارداد هایی است که توسط سیمفونی تعیین شده است، با این حال شما می‌توانید آنها را در هر نقطه‌ای تحت پوشه web ذخیره کنید.</p></blockquote>
<p>خوانندگان ریزبین متوجه شده‌اند که در هیچ کجای layout اشاره‌ای به فایل‌ main.css نشده است. اما در خروجی HTML آن را مشاهده می‌کنیم! این چگونه ممکن است؟<br />
سبک نامه‌ها بوسیله فانکشن include_stylesheets() در تگ Head فراخوانی شده است. این فانکشن یک <strong>کمک‌کننده</strong> را فراخوانی می‌کند.<br />
کمک کننده خود یک فانکشن است که توسط سیمفونی تعیین شده است و می‌تواند پارامتر‌هایی را در قالب HTML برگرداند، کمک کننده باعث صرفه‌جویی در وقت می‌شود، آنها بسته‌های کوچکی هستند که خیلی اوقات در قالب بکار برده می‌شوند. کمک‌کننده  include_stylesheets()تگ link را برای سبک‌نامه ایجاد می‌کند.<br />
در این قسمت این سوال پیش می‌آید که کمک‌کننده از کجا متوجه می‌شود که کدام سبک‌نامه را باید include‌کند؟ با ویرایش فایل view.yml می‌توان لایه view را پیکره‌بندی نمود.<br />
این پیکره‌بندی پیشفرض است که به کمک دستور generate:app ایجاد شده است:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># apps/frontend/config/view.yml</span>
default:
  http_metas:
    content-<span style="color: #000000; font-weight: bold;">type</span>: text<span style="color: #66cc66;">/</span>html
&nbsp;
  metas:
    <span style="color: #808080; font-style: italic;">#title:        symfony project</span>
    <span style="color: #808080; font-style: italic;">#description:  symfony project</span>
    <span style="color: #808080; font-style: italic;">#keywords:     symfony, project</span>
    <span style="color: #808080; font-style: italic;">#language:     en</span>
    <span style="color: #808080; font-style: italic;">#robots:       index, follow</span>
&nbsp;
  stylesheets:    <span style="color: #66cc66;">&#91;</span>main.css<span style="color: #66cc66;">&#93;</span>
&nbsp;
  javascripts:    <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span>
&nbsp;
  has_layout:     on
  layout:         layout</pre></div></div>

<p>فایل پیکره‌بندی view.yml بطور پیشفرض تنظیماتی را بروی تمامی قالب‌های application اعمال می‌کند. بعنوان مثال، مقدار stylesheet یک آرایه را برای سبک‌نامه‌هایی که باید در هر صفحه include شوند را مشخص می‌کند.</p>
<blockquote><p><strong>یادداشت</strong>: فایل view.yml به فایل main.css اشاره می‌کند نه به css/main.css. در حقیقت هر دو مشخصه با هم برابر هستند، زیرا مسیر‌های نسبی پیشوندی سیمفونی با /css همراهند.</p></blockquote>
<p>اگر تعداد فایل‌های زیادی مشخص شده باشند، سیمفونی آنها را در جای مشخص include می‌کند.</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">stylesheets:    <span style="color: #66cc66;">&#91;</span>main.css, jobs.css, job.css<span style="color: #66cc66;">&#93;</span></pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">stylesheets:    <span style="color: #66cc66;">&#91;</span>main.css, jobs.css, job.css, <span style="color: #000000; font-weight: bold;">print</span>: <span style="color: #66cc66;">&#123;</span> media: <span style="color: #000000; font-weight: bold;">print</span> <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#93;</span></pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;screen&quot; href=&quot;/css/main.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;screen&quot; href=&quot;/css/jobs.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;screen&quot; href=&quot;/css/job.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;print&quot; href=&quot;/css/print.css&quot; /&gt;</pre></div></div>

<blockquote><p><strong>نکته</strong>: فایل view.yml طرح (layout) پیشفرض برای استفاده applicationها را نیز مشخص می‌کند. بطور پیشفرض نام آن layout است و بنابراین سیمفونی تمام صفحات را با فایل layout.php آرایش می‌دهد. همچنین شما می‌توانید این پروسه را با تغییر دادن مقدار has_layout به false کاملاْ غیر فعال کنید.</p></blockquote>
<p>این رزوش کار می‌کند، اما فایل jobs.css مستلزم به وجود صفحه اصلی و فایل job.css به صفحه شغل می‌باشد. پیکره‌بندی view.yml می‌تواند بر مبنای per-module توسعه یابد. فایل view.yml را طوری تغییر می‌دهیم تا تنها فایل main.css را شامل شود.</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># apps/frontend/config/view.yml</span>
stylesheets:    <span style="color: #66cc66;">&#91;</span>main.css<span style="color: #66cc66;">&#93;</span></pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># apps/frontend/modules/job/config/view.yml</span>
indexSuccess:
  stylesheets: <span style="color: #66cc66;">&#91;</span>jobs.css<span style="color: #66cc66;">&#93;</span>
&nbsp;
showSuccess:
  stylesheets: <span style="color: #66cc66;">&#91;</span>job.css<span style="color: #66cc66;">&#93;</span></pre></div></div>

<p>در قسمت زیرین indexSuccess و showSuccess (اینها همام اسامی قالب هستند که با اکشن‌های index و show پیوست خورده‌اند، که در آینده بیشتر می‌بینیم) می‌توانید هر ورودی که زیر قسمت default پیدا می‌کنید را در فایل view.yml برنامه (application) توسعه دهید. تمام ورودی‌های خاص با پیکره‌بندی application ترکیب شده‌اند. همچنین شما می‌توانید برخی پیکره‌بندی‌ها را برای تمامی اکشن‌های یک ماژول بوسیله قسمت مخصوص all مشخص کنید.</p>
<blockquote>
<h4>اصول پیکره‌بندی در سیمفونی</h4>
<p>برای بیشتر فایل‌های پیکره‌بندی سیمفونی، همان تنظیمات می‌تواند در سطوح مختلفی مشخص شود.</p>
<ul>
<li> پیکره‌بندی پیشفرض در فریمورک تعیین شده است</li>
<li> پیکره‌بندی سراسری برای پروژه (در پوشه config)</li>
<li> پیکره‌بندی داخلی برای یک application (در پوشه apps/APP/config)</li>
<li> پیکره‌بندی داخلی انحصاری برای یک ماژول (apps/APP/MODULE/config)</li>
</ul>
<p>در زمان اجرا، سیستم پیکره‌بندی تمام مقادیر را از فایل‌های مختلف در صورت یافتن و cach کردن با هم پیوند می‌دهد تا نتیجه آن بهترین کارایی را داشته باشد.</p></blockquote>
<p>هنگامی که چیزی بوسیله فایل پیکره‌بندی، پیکره‌بندی شده باشد، همان را می‌توان بوسیله فایل‌های PHP کامل کرد. بجای ایجاد یک فایل view.yml برای ماژول job، بعنوان مثال می‌توان از کمک کننده use_stylesheet() برای include کردن استایل از یک قالب استفاده کرد:</p>
<p>همچنین می‌توانید برای include‌کردن یک استایل سراسری هم از این کمک‌کننده استفاده کنید.<br />
انتخاب یک متد یک موضوع کاملاْ سلیقه‌ای است. فایل view.yml راهی را برای تخصیص مواردی به تمام اکشن‌ها و ماژول‌ها آماده می‌کند که اینکار در یک قالب شدنی نیست. اما با این حال پیکره‌بندی کاملاْ ایستا است و و استفاده از کمک‌کننده‌ها انعطاف زیادی دارد و علاوه بر آن هر چیز سر جای خودش است: مشخصات استایل و کد HTML.<br />
ما برای پروژه jobeet از کمک‌کننده use-stylesheet() استفاده می‌کنیم. به همین علت شما می‌توانید فایل view.yml را حذف کنید.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt;!-- apps/frontend/modules/job/templates/indexSuccess.php --&gt;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> use_stylesheet<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jobs.css'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
&lt;!-- apps/frontend/modules/job/templates/showSuccess.php --&gt;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> use_stylesheet<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'job.css'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<blockquote><p><strong>یادداشت</strong>: همینطور برای فایل‌های javascript می‌توان از view.yml و یا کمک‌کننده use-javascript() استفاده کرد.</p></blockquote>
<h3>صفحه اصلی job</h3>
<p>همانطور که در روز سوم مشاهده کردید، صفحه اصلی job بوسیله اکشن index از ماژول job ایجاد شد. اکشن index یک کنترل‌کننده صفحه است و پیوندی با قالب دارد، فایل indexsuccess.php نیز قسمت view است.</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">apps<span style="color: #66cc66;">/</span>
  frontend<span style="color: #66cc66;">/</span>
    modules<span style="color: #66cc66;">/</span>
      job<span style="color: #66cc66;">/</span>
        actions<span style="color: #66cc66;">/</span>
          actions.class.php
        templates<span style="color: #66cc66;">/</span>
          indexSuccess.php</pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// apps/frontend/modules/job/actions/actions.class.php</span>
<span style="color: #000000; font-weight: bold;">class</span> jobActions <span style="color: #000000; font-weight: bold;">extends</span> sfActions
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeIndex<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">jobeet_job_list</span> <span style="color: #339933;">=</span> JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">doSelect</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Criteria<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeFooBar<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">foo</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'bar'</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">bar</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'bar'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'baz'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>این کد متغیر‌های $foo و $bar را که در قالب قابل دسترسی هستند را ایجاد می‌کند.</p>
<h4>قالب</h4>
<p>بطور پیشفرض، نام قالب با توجه به تعداد داده‌های سیمفونی با یک Action یکپارچه شده است.(نام اکشن با پسوندی از success).<br />
قالب indexSuccess.php برای تمامی مشاغل یک جدول HTML ایجاد می‌کند. این کد‌ها را مشاهده کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt;!-- apps/frontend/modules/job/templates/indexSuccess.php --&gt;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> use_stylesheet<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jobs.css'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
&lt;h1&gt;Job List&lt;/h1&gt;
&nbsp;
&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Id&lt;/th&gt;
      &lt;th&gt;Category&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
&lt;!-- more columns here --&gt;
      &lt;th&gt;Created at&lt;/th&gt;
      &lt;th&gt;Updated at&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$jobeet_job_list</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$jobeet_job</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    &lt;tr&gt;
      &lt;td&gt;
        &lt;a href=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> url_for<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'job/show?id='</span><span style="color: #339933;">.</span><span style="color: #000088;">$jobeet_job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;
          <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$jobeet_job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
        &lt;/a&gt;
      &lt;/td&gt;
      &lt;td&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$jobeet_job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCategoryId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/td&gt;
      &lt;td&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$jobeet_job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getType</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/td&gt;
&lt;!-- more columns here --&gt;
      &lt;td&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$jobeet_job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCreatedAt</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/td&gt;
      &lt;td&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$jobeet_job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUpdatedAt</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/td&gt;
    &lt;/tr&gt;
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endforeach</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  &lt;/tbody&gt;
&lt;/table&gt;
&nbsp;
&lt;a href=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> url_for<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'job/new'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;New&lt;/a&gt;</pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt;!-- apps/frontend/modules/job/templates/indexSuccess.php --&gt;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> use_stylesheet<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jobs.css'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
&lt;div id=&quot;jobs&quot;&gt;
  &lt;table class=&quot;jobs&quot;&gt;
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$jobeet_job_list</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$job</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
      &lt;tr class=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #990000;">fmod</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> ? <span style="color: #0000ff;">'even'</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'odd'</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;
        &lt;td class=&quot;location&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLocation</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/td&gt;
        &lt;td class=&quot;position&quot;&gt;
          &lt;a href=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> url_for<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'job/show?id='</span><span style="color: #339933;">.</span><span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;
            <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPosition</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
          &lt;/a&gt;
        &lt;/td&gt;
        &lt;td class=&quot;company&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCompany</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/td&gt;
      &lt;/tr&gt;
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endforeach</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  &lt;/table&gt;
&lt;/div&gt;</pre></div></div>

<div id="attachment_466" class="wp-caption aligncenter" style="width: 310px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/homepage.png"><img class="size-medium wp-image-466" title="برای مشاهده ابعاد بزرگتر کلیک کنید" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/homepage-300x192.png" alt="صفحه اصلی پروژه" width="300" height="192" /></a><p class="wp-caption-text">صفحه اصلی پروژه</p></div>
<p>در رابطه با تابع url_for() در قسمت بعد صحبت می‌کنیم.</p>
<h3>قالب صفحه شغل</h3>
<p>حالا نوبت ایجاد قالب صفحه شغل است.<br />
فایل showSuccess.php را باز کرده و محتوای زیر را با محتوای پیشفرض تغییر دهید.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt;!-- apps/frontend/modules/job/templates/showSuccess.php --&gt;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> use_stylesheet<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'job.css'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> use_helper<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Text'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
&lt;div id=&quot;job&quot;&gt;
  &lt;h1&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCompany</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/h1&gt;
  &lt;h2&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLocation</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/h2&gt;
  &lt;h3&gt;
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPosition</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    &lt;small&gt; - <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getType</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/small&gt;
  &lt;/h3&gt;
&nbsp;
  <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLogo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    &lt;div class=&quot;logo&quot;&gt;
      &lt;a href=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getUrl</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;
        &lt;img src=&quot;/uploads/jobs/<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getLogo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;
          alt=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCompany</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span> logo&quot; /&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
  &lt;div class=&quot;description&quot;&gt;
    <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> simple_format_text<span style="color: #009900;">&#40;</span><span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDescription</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  &lt;/div&gt;
&nbsp;
  &lt;h4&gt;How to apply?&lt;/h4&gt;
&nbsp;
  &lt;p class=&quot;how_to_apply&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getHowToApply</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/p&gt;
&nbsp;
  &lt;div class=&quot;meta&quot;&gt;
    &lt;small&gt;posted on <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCreatedAt</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'m/d/Y'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/small&gt;
  &lt;/div&gt;
&nbsp;
  &lt;div style=&quot;padding: 20px 0&quot;&gt;
    &lt;a href=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> url_for<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'job/edit?id='</span><span style="color: #339933;">.</span><span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;
      Edit
    &lt;/a&gt;
  &lt;/div&gt;
&lt;/div&gt;</pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// apps/frontend/modules/job/actions/actions.class.php</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeShow<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">job</span> <span style="color: #339933;">=</span> JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">retrieveByPk</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404Unless</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">job</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCreatedAt</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'m/d/Y'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<blockquote><p><strong>یادداشت</strong>: توضیحات شغل از کمک کننده simple_format_text() برای قالب بندی HTML استفاده می‌کند.<br />
از آنجایی که این کمک‌کننده از خانواده کمک‌کننده‌های text است و بصورت پیشفرض لود نمی‌شود، ما آن را بصورت دستی و با استفاده از کمک کننده use_helper() بارگذاری کردیم.</p></blockquote>
<div id="attachment_469" class="wp-caption aligncenter" style="width: 310px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/job1.png"><img class="size-medium wp-image-469" title="برای مشاهده ابعاد بزرگتر کلیک کنید" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/job1-300x242.png" alt="صفحه نمایش شغل" width="300" height="242" /></a><p class="wp-caption-text">صفحه نمایش شغل</p></div>
<h3>شیار‌ها</h3>
<p>خوب، حالا عنوان همه صفحات را در در تگ title لایه بندی مشخص می‌کنیم.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;title&gt;Jobeet - Your best job board&lt;/title&gt;</pre></div></div>

<p>اما برای صفحه شغل، اطلاعات کاربردی‌تری باید مهیا کنیم. مثل نام شرکت و موقعیت شغل.<br />
در سیمفونی هنگامی که یک ناحیه از layout برای نمایش وابسته به قالب باشد، به شیار‌ها (Slot) نیاز پیدا می‌کنیم.</p>
<div id="attachment_472" class="wp-caption aligncenter" style="width: 310px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/layout_slots.png"><img class="size-medium wp-image-472" title="برای مشاهده ابعاد بزرگتر کلیک کنید" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/layout_slots-300x82.png" alt="ساختار شیار‌ها" width="300" height="82" /></a><p class="wp-caption-text">ساختار شیار‌ها</p></div>
<p>شیاری را به layout اضافه می‌کنیم تا بتوان عنوان پویا ایجاد کرد.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">// apps/frontend/templates/layout.php
&lt;title&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> include_slot<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'title'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/title&gt;</pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">// apps/frontend/modules/job/templates/showSuccess.php
<span style="color: #000000; font-weight: bold;">&lt;?php</span> slot<span style="color: #009900;">&#40;</span>
  <span style="color: #0000ff;">'title'</span><span style="color: #339933;">,</span>
  <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'%s is looking for a %s'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCompany</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPosition</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">// apps/frontend/modules/job/templates/showSuccess.php
<span style="color: #000000; font-weight: bold;">&lt;?php</span> slot<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'title'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'%s is looking for a %s'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCompany</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getPosition</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> end_slot<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">// apps/frontend/templates/layout.php
&lt;title&gt;
  <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>include_slot<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'title'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
    Jobeet - Your best job board
  <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&lt;/title&gt;</pre></div></div>

<p>اگر شیار‌ها مشخص شده باشند، کمک‌کننده مقدار صحیح را باز می‌گرداند، بنابر‌این هنگامی که عنوان خاصی مشخص نشده باشد، مقدار پیشفرض باز می‌گردد.</p>
<blockquote><p><strong>نکته</strong>: در گذشته مشاهده کردید که یک کمک‌کننده با include_ آغاز می‌شود که محتوای HTML تولید می‌کند و در بیشتر موارد همتایی دارد که با get_ آغاز می‌شود و تنها محتوا را بر‌میگرداند.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> include_slot<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'title'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> get_slot<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'title'</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> include_stylesheets<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> get_stylesheets<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

</blockquote>
<h3>اکشن صفحه شغل</h3>
<p>این صفحه بوسیله اکشن show در متد executeShow() از ماژول job ایجاد شده‌است.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> jobActions <span style="color: #000000; font-weight: bold;">extends</span> sfActions
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> executeShow<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">job</span> <span style="color: #339933;">=</span> JobeetJobPeer<span style="color: #339933;">::</span><span style="color: #004000;">retrieveByPk</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404Unless</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">job</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>مانند اکشن index از کلاس JobeetJobPeer که برای بازگرداندن یک شغل استفاده می‌شد، حالا اینکار بوسیله متد retrieveByPk() انجام می‌گیرد.پارامتر این متد شناسه یکتای شغل است همان کلید اصلی. در قسمت بعد توضیح می‌دهیم که برای چه عبارت $request-&gt;getParameter(&#8217;id&#8217;)کلید اصلی شغل را باز‌ می‌گرداند.</p>
<blockquote><p><strong>نکته</strong>: کلاس‌های مدل ایجاد شده  متد‌های بسیاری را برای ارتباط متقابل با اشیاء پروژه دارند. مدتی را صرف مطالعه کد‌های موجود در پوشه lib/om کنید تا به قدرت نهفته در آن پی ببرید.</p></blockquote>
<p>اگر شغلی در پایگاه داده یافت نشد، کاربر را به صفحه ۴۰۴ می‌بریم. که در حقیقت کار متد forward404Unless() است.<br />
این متد یک مقدار بولی بعنوان اولین آرگومنت می‌گیرد و اگر مقدار صحیح باشد، اجرای فعلی را متوقف می‌کند.<br />
در حالت‌های خاص صفحه بنمایش درآمده برای کاربران متفاوت است. محیط prod و محیط dev را در تصاویر زیر مشاهده می‌کنید:</p>
<div id="attachment_475" class="wp-caption aligncenter" style="width: 310px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/404_prod.png"><img class="size-medium wp-image-475" title="برای مشاهده ابعاد بزرگتر کلیک کنید" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/404_prod-300x103.png" alt="صفحه ۴۰۴ در محیط prod" width="300" height="103" /></a><p class="wp-caption-text">صفحه ۴۰۴ در محیط prod</p></div>
<p style="text-align: center;">
<div id="attachment_478" class="wp-caption aligncenter" style="width: 310px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/404_dev.png"><img class="size-medium wp-image-478" title="برای مشاهده ابعاد بزرگتر کلیک کنید" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/404_dev-300x103.png" alt="صفحه ۴۰۴ در محیط dev" width="300" height="103" /></a><p class="wp-caption-text">صفحه ۴۰۴ در محیط dev</p></div>
<blockquote><p><strong>یادداشت</strong>: قبل از قرار دادن jobeet در سرور اصلی باید بدانید که چگونه می‌توان صفحه ۴۰۴ را ویرایش کرد.</p></blockquote>
<blockquote>
<h4>خانواده متد‌های forward</h4>
<p>فراخوانی forward404Unless در حقیقت برابری می‌کند با :</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404If</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">job</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>که همچنین با این نیز برابری دارد:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">job</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward404</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">forward</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'default'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'404'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>متد forward() به سمت یک اکشن دیگر از همان application هدایت می‌کند، همچنان که در مثال قبلی به اکشن ۴۰۴ ماژول default.<br />
ماژول default همراه سیمفونی است و اکشن‌های پیشفرض را برای ۴۰۴، صفحات secure و صفحه لوگین مهیا می‌کند.</p></blockquote>
<h3>درخواست‌ها و جواب‌ها</h3>
<p>هنگامی که در مرورگرتان صفحه /job و یا /job/show/id/1 را مرور می‌کنید، گردشی را براه انداخته‌اید. مرورگر درخواست‌ می‌دهد و سرور پاسخگویی باز می‌گرداند.<br />
در گذشته دیدید که سیمفونی در‌خواست‌ها را در آبجکت sfWebRequest کپسوله می‌کند.(به متدexecuteShow() نگاهی بیندازید) و علاوه بر آن سیمفونی یک فریم‌ورک شیءگرا است. جواب‌ها هم یک آبجکت از کلاس sfWebResponse هستند. می‌توانید با فراخوانی $this-&gt;getResponse()  به آبجکت پاسخ دسترسی داشته باشید. این اشیاء متد‌های مناسب زیادی برای دسترسی به اطلاعات توابع و متغیر‌های سراسری PHP تولید می‌کند.</p>
<h4>درخواست‌ها</h4>
<p>کلاس sfWebRequest کلیه آرایه‌های سراسری PHP از قبیل $_SERVER, $_COOKIE, $_GET, $_POST, and $_FILES می‌باشد.</p>
<table class="leftt" border="0" cellspacing="0">
<thead>
<tr>
<th>Method name</th>
<th>PHP equivalent</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>getMethod()</code></td>
<td><code>$_SERVER['REQUEST_METHOD']</code></td>
</tr>
<tr>
<td><code>getUri()</code></td>
<td><code>$_SERVER['REQUEST_URI']</code></td>
</tr>
<tr>
<td><code>getReferer()</code></td>
<td><code>$_SERVER['HTTP_REFERER']</code></td>
</tr>
<tr>
<td><code>getHost()</code></td>
<td><code>$_SERVER['HTTP_HOST']</code></td>
</tr>
<tr>
<td><code>getLanguages()</code></td>
<td><code>$_SERVER['HTTP_ACCEPT_LANGUAGE']</code></td>
</tr>
<tr>
<td><code>getCharsets()</code></td>
<td><code>$_SERVER['HTTP_ACCEPT_CHARSET']</code></td>
</tr>
<tr>
<td><code>isXmlHttpRequest()</code></td>
<td><code>$_SERVER['X_REQUESTED_WITH'] == 'XMLHttpRequest'</code></td>
</tr>
<tr>
<td><code>getHttpHeader()</code></td>
<td><code>$_SERVER</code></td>
</tr>
<tr>
<td><code>getCookie()</code></td>
<td><code>$_COOKIE</code></td>
</tr>
<tr>
<td><code>isSecure()</code></td>
<td><code>$_SERVER['HTTPS']</code></td>
</tr>
<tr>
<td><code>getFiles()</code></td>
<td><code>$_FILES</code></td>
</tr>
<tr>
<td><code>getGetParameter()</code></td>
<td><code>$_GET</code></td>
</tr>
<tr>
<td><code>getPostParameter()</code></td>
<td><code>$_POST</code></td>
</tr>
<tr>
<td><code>getUrlParameter()</code></td>
<td><code>$_SERVER['PATH_INFO']</code></td>
</tr>
<tr>
<td><code>getRemoteAddress()</code></td>
<td><code>$_SERVER['REMOTE_ADDR']</code></td>
</tr>
</tbody>
</table>
<p>قبلاْ با استفاده از متد getParameter() به پارامتر‌های درخواست‌ دسترسی پیدا کردیم که مقداری را از متغیر‌های سراسری GET، POST و یا PATH_INFO بر‌میگرداند.<br />
اگر می‌خواهید مطمئن باشید کا مقادیر از متغیر خاصی می‌آیند باید به ترتیب از متد‌های getGetParameter(), getPostParameter(), and getUrlParameter() استفاده کنید.</p>
<blockquote><p><strong>یادداشت</strong>: هنگامی که قصد محدود‌کردن اکشن به متدی خاص را دارید، برای مثال همنگامی که می‌خواهید اطمینان حاصل کنید که یک فرم بوسیله POST ارسال شده است، می‌توانید از متد isMethod() استفاده کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>forwardUnless<span style="color: #009900;">&#40;</span><span style="color: #000088;">$request</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>isMethod<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'POST'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

</blockquote>
<h4>پاسخ‌ها</h4>
<p>کلاس sfWebResponse متد‌های header() و setrawcookie() را پوشش می‌دهد.</p>
<table class="leftt" border="0" cellspacing="0">
<thead>
<tr>
<th>Method name</th>
<th>PHP equivalent</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>setCookie()</code></td>
<td><code>setrawcookie()</code></td>
</tr>
<tr>
<td><code>setStatusCode()</code></td>
<td><code>header()</code></td>
</tr>
<tr>
<td><code>setHttpHeader()</code></td>
<td><code>header()</code></td>
</tr>
<tr>
<td><code>setContentType()</code></td>
<td><code>header()</code></td>
</tr>
<tr>
<td><code>addVaryHttpHeader()</code></td>
<td><code>header()</code></td>
</tr>
<tr>
<td><code>addCacheControlHttpHeader()</code></td>
<td><code>header()</code></td>
</tr>
</tbody>
</table>
<p>مسلماْ کلاس sfWebResponse راهی را برای آماده کردن محتوای پاسخ (setContent()) و ارسال آن به مرورگر(send()) را ایجاد می‌کند.<br />
بالاتر در رابطه با مدیریت CSSها و Jsها در فایل view.yml و قالب صحبت کردیم. در آخر هر دو تکنیک در جوابگویی شیء addStylesheet() و addJavascript() استفاده شدند.</p>
<blockquote><p><strong>نکته</strong>: کلاس‌های <a href="http://www.symfony-project.org/api/1_2/sfAction" target="_blank"> sfAction</a> ، <a href="http://www.symfony-project.org/api/1_2/sfRequest" target="_self"> sfRequest</a> و <a href="http://www.symfony-project.org/api/1_2/sfResponse" target="_blank"> sfResponse</a> متد‌های مفید و بسیار زیادی تولید می‌کنند. به این لینک مراجعه کنید تا بیشتر در رابطه با کلاس‌های داخلی سیمفونی بدانید.</p></blockquote>
<h3>فردا همدیگر را می‌بینیم</h3>
<p>امروز به شرح الگوی طراحی استفاده شده در سیمفونی پرداختیم، کار با قالب را شروع و Layout و فایل‌های قالب را دستکاری کردیم. همچنین کمی آنها را پویا کردیم و این کار را به لطف شیار‌ها و اکشن‌ها انجام دادیم.<br />
فردا در رابطه با url_for() که امروز بکار بردیم و یکپارچه کردن با مسیر‌یابی را فرا‌خواهیم گرفت.</p>
<img src="http://www.moshtaghi.ir/weblog/?ak_action=api_record_view&id=366&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.moshtaghi.ir/2009/05/4th-symfony-jobeet/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>آموزش سیمفونی ( Jobeet &#8211; قسمت سوم)</title>
		<link>http://weblog.moshtaghi.ir/2009/04/3th-symfony-jobeet/</link>
		<comments>http://weblog.moshtaghi.ir/2009/04/3th-symfony-jobeet/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 20:20:09 +0000</pubDate>
		<dc:creator>مهدی</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[jobeet]]></category>
		<category><![CDATA[Schema]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.moshtaghi.ir/weblog/?p=358</guid>
		<description><![CDATA[بخش اول و دوم را خوانده‌اید؟ اگر نه که سعی کنید حتماْ آنها را مطالعه کنید و این کلمات (OOP, ORM, RAD, DRY, KISS, TDD, YAML, PEAR) را هم در گوگل جستجو کنید تا درک بهتری از ادامه آموزش‌ها داشته باشید.
آنهایی که علاقه زیادی به باز کردن ویرایشگر و کد‌نویسی دارند خوشحال باشند، چرا که ]]></description>
			<content:encoded><![CDATA[<blockquote><p>بخش <a title="آغاز کار با سیمفونی" href="http://www.moshtaghi.ir/weblog/2009/04/starting-with-symfony/">اول</a> و <a title="آموزش سیمفونی ( Jobeet - قسمت دوم)" href="http://www.moshtaghi.ir/weblog/2009/04/2th-symfony-jobeet/">دوم</a> را خوانده‌اید؟ اگر نه که سعی کنید حتماْ آنها را مطالعه کنید و این کلمات (<strong>OOP</strong>, <strong>ORM</strong>, RAD, DRY, KISS, TDD, <strong>YAML</strong>, <strong>PEAR</strong>) را هم در گوگل جستجو کنید تا درک بهتری از ادامه آموزش‌ها داشته باشید.</p></blockquote>
<p>آنهایی که علاقه زیادی به باز کردن ویرایشگر و کد‌نویسی دارند خوشحال باشند، چرا که آموزش امروز همین است.<br />
Data Model را در Jobeet تعریف می‌کنیم، از ORM برای ارتباط با پایگاه داده استفاده می‌کنیم و اولین Model از برنامه را ایجاد می‌کنیم.</p>
<h3>ارتباطات مدل</h3>
<p>حکایت کاربری که در قسمت قبل به ان اشاره شد، شی اصلی پروژه ما را شرح می‌دهد: مشاغل، Affiliateها و دسته‌بندی‌ها.<br />
در این قسمت دیاگرام موجودیت‌ها وابسته به هم را مشاهده می‌کنید:</p>
<div id="attachment_366" class="wp-caption aligncenter" style="width: 283px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/diagram.png"><img class="size-full wp-image-366" title="diagram" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/diagram.png" alt="دیاگرام موجودیت‌ها وابسته به هم نام" width="273" height="164" /></a><p class="wp-caption-text">دیاگرام موجودیت‌ها وابسته به هم نام</p></div>
<p><span id="more-358"></span>بعلاوه در شرح ستون‌ها، یک فیلد با نام created_at با جدول اضافه کردیم. سیمفونی اینچنین فیلد‌هایی را شناسایی کرده و مقدار ساعت جاری سیستم را به هنگاه ایجاد رکورد در آن ثبت می‌کند. همچنین فیلد updated_at، که مقدار زمان در هنگاه بروز شدن رکورد در آن ثبت می‌شود.</p>
<h3>طرح (The Schema)</h3>
<p>بدیهی است که برای ذخیره سازی مشاغل و … به یک پایگاه داده رابطه‌ای نیازمندیم. اما سیممفونی یک فریم‌ورک شی‌گرا می‌باشد، و ما می‌خواهیم تا در هر زمان بر اشیا کنترل داشته باشیم. یعنی، بجای نوشتن عبارات SQL برای بازیافت رکورد‌ها، از اشیا استفاده می‌کنیم تا سریعتر به جواب برسیم.<br />
اطلاعات پایگاه داده‌های رابطه‌ای باید بصورت مدل اشیا (Object Model) نگاشته شوند. اینکار را با یک ابزار ORM می‌توان انجام داد.<br />
سیمفونی، <a href="http://propel.phpdb.org/" target="_blank">Propel</a> و <a href="http://www.doctrine-project.org/" target="_blank">Doctrine</a> را همراه خود دارد و ما در این آموزش از Propel استفاده می‌کنیم.<br />
ORM برای ایجاد کلاس‌های مربوطه به شرح جداول و ارتباطات انها نیازمند است و ما دو راه برای ایجاد آن داریم: بوسیله introspecting an existing database و یا انجام دستی اینکار!</p>
<blockquote><p><strong>یادداشت:</strong> ابزاری وجود دارند که امکان ساخت پایگاه داده را بصورت گرافیکی (برای مثال <a href="http://www.fabforce.net/dbdesigner4/" target="_blank">Fabforce&#8217;s Dbdesigner</a>) و تولید مستقیم یک فایل schema.xml (بوسیله <a href="http://blog.tooleshed.com/docs/dbd2propel/transform.php" target="_blank">DB Designer 4 TO Propel Schema Converter</a> ).</p></blockquote>
<p>از آنجایی که پایگاه داده ما هنوز ایجاد نشده، فایل طرح را به شکل دستی ایجاد می‌کنیم و فایل خالی config/schema.yml را بدین صورت ویرایش می‌کنیم.</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># config/schema.yml</span>
propel:
jobeet_category:
id:           ~
name:         <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>, required: true, index: unique <span style="color: #66cc66;">&#125;</span>
&nbsp;
jobeet_job:
id:           ~
category_id:  <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: integer, foreignTable: jobeet_category, foreignReference: id, required: true <span style="color: #66cc66;">&#125;</span>
<span style="color: #000000; font-weight: bold;">type</span>:         <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#125;</span>
company:      <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>, required: true <span style="color: #66cc66;">&#125;</span>
logo:         <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#125;</span>
<span style="color: #000066;">url</span>:          <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#125;</span>
position:     <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>, required: true <span style="color: #66cc66;">&#125;</span>
location:     <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>, required: true <span style="color: #66cc66;">&#125;</span>
description:  <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: longvarchar, required: true <span style="color: #66cc66;">&#125;</span>
how_to_apply: <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: longvarchar, required: true <span style="color: #66cc66;">&#125;</span>
token:        <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>, required: true, index: unique <span style="color: #66cc66;">&#125;</span>
is_public:    <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: boolean, required: true, default: <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#125;</span>
is_activated: <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: boolean, required: true, default: <span style="color: #cc66cc;">0</span> <span style="color: #66cc66;">&#125;</span>
email:        <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>, required: true <span style="color: #66cc66;">&#125;</span>
expires_at:   <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: timestamp, required: true <span style="color: #66cc66;">&#125;</span>
created_at:   ~
updated_at:   ~
&nbsp;
jobeet_affiliate:
id:           ~
<span style="color: #000066;">url</span>:          <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>, required: true <span style="color: #66cc66;">&#125;</span>
email:        <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>, required: true, index: unique <span style="color: #66cc66;">&#125;</span>
token:        <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>, required: true <span style="color: #66cc66;">&#125;</span>
is_active:    <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: boolean, required: true, default: <span style="color: #cc66cc;">0</span> <span style="color: #66cc66;">&#125;</span>
created_at:   ~
&nbsp;
jobeet_category_affiliate:
category_id:  <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: integer, foreignTable: jobeet_category, foreignReference: id, required: true, primaryKey: true, onDelete: cascade <span style="color: #66cc66;">&#125;</span>
affiliate_id: <span style="color: #66cc66;">&#123;</span> <span style="color: #000000; font-weight: bold;">type</span>: integer, foreignTable: jobeet_affiliate, foreignReference: id, required: true, primaryKey: true, onDelete: cascade <span style="color: #66cc66;">&#125;</span></pre></div></div>

<blockquote><p><strong>یادداشت:</strong> اگر مصمم هستید که پایگاه داده خود را بوسیله عبارات SQL ایجاد کنید، می‌توانید بوسیله اجرای دستور propel:build-schema یک schema.yml مشابه ایجاد کنید.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php symfony propel:build-schema</pre></div></div>

<p>طرح یا همان schema برگردانی از موجودیت‌های مرتبط با هم در قالب <a title="سایت رسمی YAML" href="http://yaml.org/" target="_blank">YAML</a> است که یک زبان ساده برای شرح دادن داده‌ها می‌باشد.</p></blockquote>
<p>فایل schema.yml شامل توضیحاتی از کلیه جداول و ستون‌های آنها است. هر ستون توضیحاتی اینچنین دارد:</p>
<ul>
<li><strong>type: </strong>نوع ستون</li>
<li><strong>required: </strong>اگر می‌خواهی ستونی اجباری باشد، مقدار ان را true قرار می‌دهید.</li>
<li><strong>index: </strong>اگر می‌خواهید ستونی را به عنوان ایندکس تعیین کنید مقدار آن را true و یا برای یکتا بودن مقدار unique را وارد کنید.</li>
<li><strong>primaryKey: </strong>تعیین ستونی به عنوان کلید اصلی جدول</li>
<li><strong>foreignTable, foreignReference:</strong> مشخص کردن ستونی به عنوان کلید خارجی به جدولی دیگر.</li>
</ul>
<p>ستون‌هایی که با مقدار ~ تنظیم شده‌اند، همان معنی null را می‌دهد. (id, created_at, and updated_at) که سیمفونی خودکار بهترین پیکره بندی را در نظر می‌گیرد.(کلید اصلی برای id و مقدار timestamp برای created_at و updated_at)</p>
<blockquote><p><strong>یادداشت:</strong> ویژگی ON DELETE رفتار کلید‌های خارجی را تعیین می‌کند، propel از CASCADE و  SETNUL و RESTRICT پشتیبانی می‌کند.<br />
برای مثال، هنگامی که رکورد یک شغل پاک می‌شود، تمام jobeet_category_affiliateهای مرتبط با رکورد‌ها باید به صورت خودکار از پایگاه داده‌ پاک شوند و یا …</p></blockquote>
<h3>پایگاه داده</h3>
<p>تمامی پایگاه‌ داده‌هایی که توسط <a title="لایه‌ای بین شما و پایگاه داده" href="http://ir.php.net/pdo" target="_blank">PDO</a> پشتیبانی می‌شوند، در فریمورک سیمفونی نیز قابلیت کاربرد را دارند. PDO یک لایه مستقل پایگاه داده (DataBase abstraction layer) همراه PHP است که باعث می‌شود تا برنامه شما با هر پایگاه داده‌ای براحتی کار کند و نیاز به تغییر در کد‌ها را نداشته‌ باشید. ما برای این پروژه از MySQL استفاده می‌کنیم.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ mysqladmin <span style="color: #660033;">-uroot</span> <span style="color: #660033;">-pmYsEcret</span> create jobeet</pre></div></div>

<blockquote><p><strong>یادداشت:</strong> شما برای انتخاب سایر پایگاه‌های داده مجازید. سازگار کردن کد‌هایی که می‌نویسیم کار دشواری نیست زیرا از ORM برای نوشتن کد‌های SQL استفاده می‌کنیم.</p></blockquote>
<p>در اینجا باید به سیمفونی اطلاع دهیم که برای این پروژه از پایگاه داده MySQL استفاده کند.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php symfony configure:database <span style="color: #ff0000;">&quot;mysql:host=localhost;dbname=jobeet&quot;</span> root password</pre></div></div>

<p>دستور configure:database برای دسترسی به پایگاه داده، سه مقدار دریافت می‌کند: <a href="http://www.php.net/manual/en/pdo.drivers.php" target="_blank">PDO DNS</a>، نام کاربری و کلمه عبور.</p>
<blockquote><p><strong>یادداشت: </strong>این دستور پیکره‌بندی پایگاه داده را در فایل config/databases.yml قرار می‌دهد. بنابراین بجای استفاده از دستور می‌توتنید اینکار را بطور دستی انجام دهید.</p></blockquote>
<h3>ORM</h3>
<p>به شما پیشنهاد می‌کنم اگر از هویت ORM مطلع نیستید <a title="ORM چیست - روزنوشت‌های الهام محمدنژاد" href="http://nhibernate.wordpress.com/2009/02/14/what-is-orm-object-relational-mapping/" target="_blank">این مطلب</a> را حتماْ بخوانید و سپس ادامه این مطلب را مطالعه فرمائید.</p>
<p>به لطف توضیحات پایگاه داده در فایل schema.yml، می‌توانیم از برخی وظایف و دستورات درونی propel برای ساخت عبارات SQLی که برای ایجاد جداول مورد نیاز است استفاده کنیم:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php symfony propel:build-sql</pre></div></div>

<p>دستور propel:build-sql عبارات را در پوشه data/sql ایجاد می‌کند، و موتور پایگاه داده را برای پیکره‌بندی ما بهینه می‌کند.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># snippet from data/sql/lib.model.schema.sql</span>
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`jobeet_category`</span>
<span style="color: #66cc66;">&#40;</span>
<span style="color: #ff0000;">`id`</span> INTEGER  <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
<span style="color: #ff0000;">`name`</span> VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span>  <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
<span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`id`</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
<span style="color: #993333; font-weight: bold;">UNIQUE</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #ff0000;">`jobeet_category_U_1`</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`name`</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span>Type<span style="color: #66cc66;">=</span>InnoDB;</pre></div></div>

<p>در حقیقت برای ایجاد جداول به دستور propel:insert-sql نیاز است.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php symfony propel:insert-sql</pre></div></div>

<p>از آنجایی که این دستور جداول فعلی را قبل از ایجاد جداول جدید حذف می‌کند، شما ملزم هستید تا این عملیات را تائید کنید. با اضافه کردن ویژگی –no-confirmation باعث کنار گذاشتن هر سوالی خواهید شد.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php symfony propel:insert-sql <span style="color: #660033;">--no-confirmation</span></pre></div></div>

<blockquote><p><strong>نکته:</strong> برای هر ابزار در خط فرمان سیمفونی یک راهنمای توکار تعبیه شده که شما می‌توانید به شکل زیر از آنها استفاده کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php symfony <span style="color: #7a0874; font-weight: bold;">help</span> propel:insert-sql</pre></div></div>

<p>این راهنما لیستی از مقادیر و متغیر‌های قابل استفاده در دستور مورد نظر را لیست می‌کند و مقدار پیشفرض هر کدام را به شما نشان خواهد داد و برای شما چندین مثال کاربردی را ذکر می‌کند.</p></blockquote>
<p>همچنین ORM کلاس‌هایی را که برای نگاشتن رکورد‌های جدول بروی اشیا است را تولید می‌کند.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php symfony propel:build-model</pre></div></div>

<p>وظیفه propel:build-model این است که فایل های PHPرا در پوشه lib/model ایجاد می‌کند تا بتوانند با پایگاه داده تعامل داشته باشند.<br />
با نگاهی به فایل‌های ایجاد شده، متوجه خواهید شد که propel برای هر جدول ۴ کلاس ایجاد کرده است. بطور مثال برای جدول jobeet_job</p>
<ul>
<li> JobeetJob: اشیای این کلاس رکوردی از جدول jobeet_job را نمایش می‌دهند. این کلاس در حالت پیشفرض خالی است.</li>
<li>BaseJobeetJob: این کلاس والد کلاس JobeetJob است و هر زمان که propel:build-model را اجرا کنید، این کلاس مقدم است، بنابراین تمام تنظیمات بروی کلاس JobeetJob اعمال می‌شوند.</li>
<li>JobeetJobPeer: این کلاس یک متد ایستا را مشخص می‌کند که اساساْ مجموعه‌ای از اشیا JobeetJob را بر می‌گرداند. کلاس بطور پیشفرض خالی است.</li>
<li>BaseJobeetJobPeer: کلاس والد کلاس JobeetJobPeer است و هر زمان که propel:build-model را اجرا کنید، این کلاس مقدم است، بنابراین تمام تنظیمات بروی کلاس JobeetJobPeer اعمال می‌شوند.</li>
</ul>
<p>مقادیر ستون یک رکورد بوسیله مدل آبجکت که از برخی ابزار دسترسی و تغییر استفاده می‌کنند قابل دستکاری هستند.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$job</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> JobeetJob<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$job</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>setPosition<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Web developer'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$job</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>save<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$job</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getPosition<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$job</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>delete<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>همچنین می‌توان بوسیله مرتبط ساختن اشیا به یکدیگر، کلید‌های خارجی را مشخص کرد.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$category</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> JobeetCategory<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$category</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>setName<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Programming'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$job</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> JobeetJob<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$job</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>setCategory<span style="color: #009900;">&#40;</span><span style="color: #000088;">$category</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>دستور propel:build-all یک میانبر برای وظایفی است که در این بخش آنها را اجرا می‌کنیم. در حال حاضر اجرای این وظیفه منجر به ساخت فرم‌ها و اعتبار‌سنج‌ها برای کلاس‌های مدل jobeet می‌شود.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php symfony propel:build-all <span style="color: #660033;">--no-confirmation</span></pre></div></div>

<p>در پایان این قسمت اعتبار سنج‌ها را در عمل مشاهده می‌کنید و فرم‌ها نیز در بخش ۱۰ کاملاْ شرح داده می‌شوند.<br />
با توجه به اینکه شما می‌خواهید پس از این را مشاهده کنید، سیمفونی خودکار کلاس‌های PHP را برای شما لود می‌کند، که بدین معنی است که هیچگاه نیاز به استفاده از require در کدتان ندارید. و این تنها یکی از بیشمار مواردی است که سیمفونی بطور خودکار برای توسعه دهندگان فراهم می‌کند. اما نکته اینجا است که هر زمان شما کلاس جدیدی ایجاد کردید، نیازمند به پاک کردن cache هستید. از آنجایی که propel:build-model کلاس‌های جدید زیادی تولید می‌کند، باید cache را پاک کنید.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php symfony cache:<span style="color: #c20cb9; font-weight: bold;">clear</span></pre></div></div>

<blockquote><p><strong>نکته:</strong> دستورات سیمفونی از یک فضای نام و یک نام برای وظیفه ساخته شده‌اند. هر کدام می‌توانند کوتاه و مختصر شوند تا شباهت کمتری با سایر دستورات داشته باشند. دستورات زیر با دستور cache:clear برابری می‌کنند:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php symfony cache:cl
$ php symfony ca:c</pre></div></div>

<p>اما این وظیفه بقدری استفاده می‌شود که بهتر است بسیار کوتاه‌تر شود!</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php symfony <span style="color: #c20cb9; font-weight: bold;">cc</span></pre></div></div>

</blockquote>
<h3>داده‌های اولیه</h3>
<p>جداول پایگاه‌داده ساخته شده‌اند، اما داده‌ای در آنها وجود ندارد. برای هر برنامه تحت وب ۳ نوع داده وجود دارد:</p>
<ul>
<li><strong>داده‌های اولیه:</strong> برنامه برای کار کردن به این داده‌ها نیازمند است. برای مثال، Jobeet به دسته‌بندی‌های اولیه نیازمند است. در غیر این صورت هیچ کس نمی‌تواند شغلی را ثبت کند! همانطور که برای آماده‌سازی بستر ورود به backend برنامه نیز به یک کاربر مدیر نیازمندیم.</li>
<li><strong>داده‌های آزمایشی:</strong> این داده‌ها برای آزمایش برنامه مورد استفاده قرار می گیرند.</li>
<li><strong>داده‌های کاربران:</strong> داده‌هایی که طی عمر معمولی برنامه توسط کاربران تولید می‌شوند.</li>
</ul>
<p>هر زمانی که سیمفونی جداول پایگاه داده را ایجاد می‌کند، تمامی داده‌ها از بین می‌روند! می‌توان برای حفظ این داده‌ها یک اسکریپت PHP نوشت و یا یک عبارت SQL را در برنامه MySQL اجرا کرد. اما چون این نیازی است که بسیار مورد استفاده قرار می‌گیرد، راه بهتر با سیمفونی وجود دارد.<br />
ایجاد فایل YAML در پوشه data/fixtures/ و استفاده از دستور propel:data-load برای بارگذاری انها در پایگاه داده.<br />
ابتدا فایل‌های fixture زیر را ایجاد کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># data/fixtures/010_categories.yml</span>
JobeetCategory:
design:        <span style="color: #66cc66;">&#123;</span> name: Design <span style="color: #66cc66;">&#125;</span>
programming:   <span style="color: #66cc66;">&#123;</span> name: Programming <span style="color: #66cc66;">&#125;</span>
manager:       <span style="color: #66cc66;">&#123;</span> name: Manager <span style="color: #66cc66;">&#125;</span>
administrator: <span style="color: #66cc66;">&#123;</span> name: Administrator <span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># data/fixtures/020_jobs.yml</span>
JobeetJob:
job_sensio_labs:
category_id:  programming
<span style="color: #000000; font-weight: bold;">type</span>:         full-time
company:      Sensio Labs
logo:         sensio-labs.gif
<span style="color: #000066;">url</span>:          http:<span style="color: #808080; font-style: italic;">//www.sensiolabs.com/</span>
position:     Web Developer
location:     Paris, France
description:  <span style="color: #66cc66;">|</span>
You've already developed websites with symfony <span style="color: #b1b100;">and</span> you want to
work with Open-Source technologies. You have a minimum of <span style="color: #cc66cc;">3</span>
years experience in web development with PHP <span style="color: #b1b100;">or</span> Java <span style="color: #b1b100;">and</span> you
wish to participate to development of Web <span style="color: #cc66cc;">2.0</span> sites using the
best frameworks available.
how_to_apply: <span style="color: #66cc66;">|</span>
Send your <span style="color: #000000; font-weight: bold;">resume</span> to fabien.potencier <span style="color: #66cc66;">&#91;</span>at<span style="color: #66cc66;">&#93;</span> sensio.com
is_public:    true
is_activated: true
token:        job_sensio_labs
email:        job<span style="color: #66cc66;">@</span>example.com
expires_at:   <span style="color: #cc66cc;">2010</span>-<span style="color: #cc66cc;">10</span>-<span style="color: #cc66cc;">10</span>
&nbsp;
job_extreme_sensio:
category_id:  design
<span style="color: #000000; font-weight: bold;">type</span>:         part-time
company:      Extreme Sensio
logo:         extreme-sensio.gif
<span style="color: #000066;">url</span>:          http:<span style="color: #808080; font-style: italic;">//www.extreme-sensio.com/</span>
position:     Web Designer
location:     Paris, France
description:  <span style="color: #66cc66;">|</span>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed <span style="color: #000000; font-weight: bold;">do</span>
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in.
&nbsp;
Voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa
qui officia deserunt mollit anim id est laborum.
how_to_apply: <span style="color: #66cc66;">|</span>
Send your <span style="color: #000000; font-weight: bold;">resume</span> to fabien.potencier <span style="color: #66cc66;">&#91;</span>at<span style="color: #66cc66;">&#93;</span> sensio.com
is_public:    true
is_activated: true
token:        job_extreme_sensio
email:        job<span style="color: #66cc66;">@</span>example.com
expires_at:   <span style="color: #cc66cc;">2010</span>-<span style="color: #cc66cc;">10</span>-<span style="color: #cc66cc;">10</span></pre></div></div>

<blockquote><p><strong>یادداشت:</strong> فایل fixture شغل به دو فایل تصویری اشاره دارد که می‌توانیدآنها را از <a href="http://www.symfony-project.org/get/jobeet/sensio-labs.gif" target="_blank">اینجا</a> و <a href="http://www.symfony-project.org/get/jobeet/extreme-sensio.gif" target="_blank">اونجا</a> دریافت کرده و در پوشه uploads/jobs/ ذخیره کنید.</p></blockquote>
<p>فایل‌های fixture در قالب YAML نوشته شده‌اند و Model Object‌ها را مشخص می‌کنند. توسط نامی یکتا برچسب خورده‌اند.(برای مثال، ما دو شغل را با job_sensio_labs و job_extreme_sensio نشانه گذاری کردیم) این برچسب‌ها در پیوند اشیا مرتبط با هم کاربرد‌های بزرگی دارند، بدون مشخص کردن کلید‌های اصلی (که بارها بطور خودکار افزایش پیدا کرده و نمی‌تواند تنظیم شود) برای مثال: دسته بندی شغل job_sensio_labs مقدار programming است که مسلماْ برچسب programming را بخود می‌گیرد.</p>
<blockquote><p><strong>نکته: </strong>در فایل YAML، هنگامی که یک رشته بخواهد شامل شکست خط شود(به خط بعد منتقل شود)، (همچون ستون Description) می‌توان با استفاده از پایپ ( | ) برای تعریف محتوای چند خطی استفاده کرد.</p></blockquote>
<p>اگر‌چه فایل‌های fixture می‌توانند شامل اشیایی از یک یا چند مدل باشند، اما ما می‌توانیم به ازای هر مدل یک  فایل fixture ایجاد کنیم.</p>
<blockquote><p><strong>نکته:</strong> شماره‌های پیشوندی برای نام فایل‌ها. این یک راه ساده برای کنترل بروی نظم در بارگذاری داده‌ها است. در مراحل بعدی اگر نیازی به درج یک فایل fixture جدید پیدا کردیم، براحتی می‌توانیم شماره‌ای را از بین این‌دو انتخاب کنیم.</p></blockquote>
<p>در یک فایل fixture، احتیاجی به مشخص کردن مقادیر تمام ستون ها نیست. در این صورت سیمفونی مقادیر مشخص شده پیشفرض در نمای پایگاه داده استفاده می‌کند و از propel برای بارگذاری داده‌ها در وایگاه داده بهره می‌برد.<br />
تمامی این رفتار‌های درونی (نظیر تنظیمات خودکار در ستون‌های craeted_at و updated_at) و رفتار‌هایی که ممکن است به کلاس‌های مدل اضافه کنید، فعال هستند.<br />
بارگیری داده‌های اولیه بوسیله اجرای دستور propel:data-load بسیار آسان است.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php symfony propel:data-load</pre></div></div>

<blockquote>
<p><strong>نکته:</strong> دستور propel:build-all-load میانبری برای دستور propel:build-all است که به دنبال دستور propel:data-load می‌آید.</p></blockquote>
<h3>مشاهده نتیجه کار در مرورگر</h3>
<p>ما از محیط خط فرمان بسیار استفاده کردیم، اما اینکار زیاد هیجان انگیز نیست، مخصوصاْ برای اینکار (طراحی وب) حالا تمام چیز‌هایی که برای ساخت صفحه وبی که با پایگاه داده تعامل کند را داریم.<br />
ببینید که چگونه باید لیست مشاغل را مشاهده کنیم، چگونه مشاغل فعلی را ویرایش کنیم و چگونه شغلی را پاک کنیم. با توجه به توضیحات روز اول، یک پروژه سیمفپنی مجموعه ای از Applicationها است. Applicationها به ماژول‌ها تقسیم شده‌اند و یک ماژول از کد‌های PHP تشکیل شده که نشان‌ دهنده ویژگی‌های Application هستند (ماژول API)، و یا مجموعه‌ای از کار‌هایی هستند که کاربران می‌توانند بروی Model Object انجام دهند.(ماژول شغل)<br />
سیمفونی بطور خودکار ماژولی برای تهیه ویژگی‌های پایه مدل را ایجاد می‌کند.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php symfony propel:generate-module <span style="color: #660033;">--with-show</span> <span style="color: #660033;">--non-verbose-templates</span> frontend job JobeetJob</pre></div></div>

<p>همانطور که به همراه بیشتر دستورات سیمفونی، برخی از فایل‌ها و پوشه‌ها در پوشه apps/frontend/modules/job/ ایجاد می‌شود، دستور propel:generate-module هم یک ماژول job برای مدل JobeetJob را در قسمت Frontend برنامه ایجاد می‌کند.</p>
<table class="doc_table" border="0">
<thead>
<tr>
<th>پوشه</th>
<th>شرح</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>actions/</code></td>
<td>اکشن‌های ماژول</td>
</tr>
<tr>
<td><code>templates/</code></td>
<td>قالب ماژول</td>
</tr>
</tbody>
</table>
<p>فایل‌ actions/actions.class.php تمامی action‌های مجاز را برای ماژول job مشخص می‌کند.</p>
<table class="doc_table" border="0" cellspacing="0">
<thead>
<tr>
<th>نام اکشن</th>
<th>شرح</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>index</code></td>
<td>نمایش رکورد‌های جدول</td>
</tr>
<tr>
<td><code>show</code></td>
<td>نمایش فیلد‌ها و مقادیر انها برای رکورد‌‌های مشخص</td>
</tr>
<tr>
<td><code>new</code></td>
<td>نمایش فرم برای ایجاد یک رکورد جدید</td>
</tr>
<tr>
<td><code>create</code></td>
<td>ایجاد یک رکورد جدید</td>
</tr>
<tr>
<td><code>edit</code></td>
<td>نمایش فرم برای ویرایش رکورد جاری</td>
</tr>
<tr>
<td><code>update</code></td>
<td>بروز‌رسانی رکورد با توجه به مقادیر ثبت شده</td>
</tr>
<tr>
<td><code>delete</code></td>
<td>حذف یک رکورد معین از جدول</td>
</tr>
</tbody>
</table>
<p>حال شما می توانید ماژول job را در مرورگر آزمایش کنید.</p>

<div class="wp_syntax"><div class="code"><pre class="io" style="font-family:monospace;">http:<span style="color: #808080; font-style: italic;">//jobeet.localhost/frontend_dev.php/job</span></pre></div></div>

<p style="text-align: center;">
<div id="attachment_400" class="wp-caption aligncenter" style="width: 556px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/job.png"><img class="size-full wp-image-400" title="job" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/job.png" alt="نمایش ماژول job را در مرورگر" width="546" height="424" /></a><p class="wp-caption-text">نمایش ماژول job را در مرورگر</p></div>
<p>اگر بخواهید شغلی را ویرایش کنید، می‌توانید استثنا (F – ی – L – ت &#8211; R) قائل شوید زیرا سیمفونی یک نمونه متنی (text representation) از دسته‌بندی‌ها را احتیاج دارد.<br />
یک نمونه شی PHP می‌تواند بوسیله متد منطقی __toString() مشخص شود. نمونه متنی یک رکورد دسته‌بندی باید در کلاس مدل JobeetCategory مشخص شده باشد.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/model/JobeetCategory.php</span>
<span style="color: #000000; font-weight: bold;">class</span> JobeetCategory <span style="color: #000000; font-weight: bold;">extends</span> BaseJobeetCategory
<span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __toString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>حال هر زمان که سیمفونی به یک نمونه متنی احتیاج داشته باشد، متد __toString() فراخوانی شده و یک نام را برای دسته بندی بر می‌گرداند. ازآنجایی که چندین نقطه به یک نمونه متنی احتیاج داریم، این متد را برای هر کلاس مدلی تعریف می‌کنیم.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/model/JobeetJob.php</span>
<span style="color: #000000; font-weight: bold;">class</span> JobeetJob <span style="color: #000000; font-weight: bold;">extends</span> BaseJobeetJob
<span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __toString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #b1b100;">return</span> <span style="color: #990000;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'%s at %s (%s)'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getPosition<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getCompany<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getLocation<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// lib/model/JobeetAffiliate.php</span>
<span style="color: #000000; font-weight: bold;">class</span> JobeetAffiliate <span style="color: #000000; font-weight: bold;">extends</span> BaseJobeetAffiliate
<span style="color: #009900;">&#123;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __toString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>getUrl<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>اینگونه شما می‌توانید شغل جدیدی ساخته و یا آن را ویرایش کنید. سعی کنید یک فیلد ضروری را خالی گذاشته و یا داده‌های غیر مجاز وارد کنید. درست است!!! سیمفونی بطور خودکار و با توجه به نمای پایگاه داده (database schema) اعتبار سنج‌های کلی را ایجاد کرده است.</p>
<h3>فردا همدیگر را می‌بینیم</h3>
<p>کار امروز تمام شد. ما کد‌هایی را نوشتیم که خالی از اشکال نیست. با این‌حال باآنها کار کردیم و نتیجه هم گرفتیم. اما به یاد داشته باشید این بدان معنا نیست که کد‌ها عاری از حفره و مشکل هستند.<br />
اگر شما هنوز احساس خستگی نمی‌کنید و می‌خواهید کد‌های نوشته شده را مطالعه کنید تا متوجه چگونگی کار کردن آن شوید که هیچ، اما در غیر اینصورت منتظر باشید تا در قسمت بعدی در رابطه با <a title="Model view controller" href="http://en.wikipedia.org/wiki/Model-view-controller" target="_blank">معماری MVC</a> با هم صحبت کنیم.</p>
<p>همچون سایر روز‌ها کد‌های امروز هم در SVN موجود می‌باشند. از تگ release_day_03 استفاده کنید.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">svn</span> <span style="color: #c20cb9; font-weight: bold;">co</span> http:<span style="color: #000000; font-weight: bold;">//</span>svn.jobeet.org<span style="color: #000000; font-weight: bold;">/</span>propel<span style="color: #000000; font-weight: bold;">/</span>tags<span style="color: #000000; font-weight: bold;">/</span>release_day_03<span style="color: #000000; font-weight: bold;">/</span> jobeet<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

</pre>
<img src="http://www.moshtaghi.ir/weblog/?ak_action=api_record_view&id=358&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.moshtaghi.ir/2009/04/3th-symfony-jobeet/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>آموزش سیمفونی ( Jobeet &#8211; قسمت دوم)</title>
		<link>http://weblog.moshtaghi.ir/2009/04/2th-symfony-jobeet/</link>
		<comments>http://weblog.moshtaghi.ir/2009/04/2th-symfony-jobeet/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 19:28:48 +0000</pubDate>
		<dc:creator>مهدی</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[jobeet]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.moshtaghi.ir/weblog/?p=347</guid>
		<description><![CDATA[توصیه می‌کنم قبل از مطالعه این مطلب حتماْ قسمت اول را مطالعه فرمائید.
تا کنون هیچ کدی با زبان php ننوشته‌ایم. با این حال محیط کاریمان را راه‌اندازی کردیم، پروژه‌ای خالی در سیمفونی ایجاد کردیم و از برخی پیشفرض‌های امنیتی خاطر جمع شدیم.
حالا شما می‌توانید صفحه پیشفرض را برای پروژه‌های خالی سیمفونی مشاهده کنید.
اما بیشتر از ]]></description>
			<content:encoded><![CDATA[<p>توصیه می‌کنم قبل از مطالعه این مطلب حتماْ <a title="آغاز کار با سیمفونی" href="http://www.moshtaghi.ir/weblog/2009/04/starting-with-symfony/">قسمت اول</a> را مطالعه فرمائید.</p>
<p>تا کنون هیچ کدی با زبان php ننوشته‌ایم. با این حال محیط کاریمان را راه‌اندازی کردیم، پروژه‌ای خالی در سیمفونی ایجاد کردیم و از برخی پیشفرض‌های امنیتی خاطر جمع شدیم.<br />
حالا شما می‌توانید صفحه پیشفرض را برای پروژه‌های خالی سیمفونی مشاهده کنید.</p>
<p>اما بیشتر از اینها باید پیش رفت. باید تمام جزئیات ریز و درشت توسعه برنامه در سیمفونی را فرا گرفت. اما امروز دقایقی را به شرح احتیاجاتی می‌پردازیم که در این پروژه به آنها نیاز است.</p>
<h2>زیر و بم پروژه</h2>
<p>Jobeet یک تخته اعلانات کاریابی کدباز است. براحتی قابل استفاده و توسعه است و می‌تواند در وبسایت شما هم بکار رود. از آخرین تکنولوژی‌های وب۲ بهره می‌گیرد و همچنین برای ارتباط متقابل با فعالیت‌های برنامه نویسی feed و API تولید می‌کند.<span id="more-347"></span></p>
<h2>داستان پروژه jobeet</h2>
<p>قبل از شیرجه به درون کد‌ها و شروع کد‌نویسی، لازم است تا اندکی بیشتر به شرح پروژه بپردازیم. در بخش‌های پائین، به تشریح خصوصیاتی می‌پردازیم که قصد اجرای آن را در نسخه اول پروژه داریم.</p>
<p>وبسایت Jobeet چهار نوع کاربر دارد.<br />
<strong>Admin: </strong>صاحب وبسایت!<br />
<strong>User: </strong>جهت یافتن شغل وبسایت را مشاهده می‌کند.<br />
<strong>Poster: </strong>برای پست کردن یک شغل به وبسایت می‌آید.<br />
<strong>Affiliate: </strong>برخی از مشاغل را در وبسایت خود منتشر می‌کند.</p>
<p>پروژه Jobeet دو بخش را در بر دارد. یکی بخش frontend ، مکانی که کاربران با وبسایت تعامل دارند (F1 تا F7) و دیگری Backend، جایی که مدیر، به مدیریت خود می‌پردازد. (B1 تا B3)<br />
بخش Backend محافظت شده است و برای دسترسی به آن اعتبار نامه نیاز است.</p>
<h3>F1: صفحه اصلی که کاربران آخرین مشاغل را در آن مشاهده می‌کنند:</h3>
<p>این مشاغل بر حسب دسته و مکان‌شان ذخیره شده‌اند و هرچه جدید‌تر باشند، بالاتر قرار می‌گیرند.<br />
در این صفحه تنها مکان، وضعیت و شرکت هر شغل قابل مشاهده است. برای هر دسته تنها ۱۰ شغل آخر به نمایش در می‌آیند و یک پیوند امکان لیست شدن مشاغل موجود در یک دسته بندی را ایجاد می‌کند. (F2)<br />
کاربر می‌تواند لیست موجود را با توجه به نیازش پالایش کند (F3) و یا شغلی جدید ارسال کند. (F5)</p>
<h3>F2: کاربر می‌تواند بین مشاغل موجود در یک دسته پرس و جو کند:</h3>
<p>هنگامی که کاربر بروی نام دسته و یا More Jobs کلیک می‌کند، تمامی مشاغل موجود در آن دسته را در لیستی که بر حسب تاریخ مرتب شده است را مشاهده می‌کند.<br />
لیست‌ها بصورت ۲۰ لینک در هر صفحه، صفحه بندی شده‌اند.</p>
<h3>F3: کاربر می‌تواند لیست را با استفاده از کلمه‌ای کلیدی پالایش کند:</h3>
<p>کاربران می‌توانند با توجه به کلمه‌ای کلیدی به جستجو بپردازند. این کلمات کلیدی در مکان، وضعیت، دسته و یا مشخصات شرکت جستجو می‌شوند.</p>
<h3>F4: کاربر بروی عنوان شغل کلیک می‌کند تا جزئیات را بررسی کند:</h3>
<p>کاربران می‌توانند یک شغل را از لیست انتخاب کرده و جزئیات آن را مشاهده کنند.</p>
<h3>F5: کاربر می‌توتند شغلی جدید پست گند:</h3>
<p>کاربران شغلی را پست می‌کنند. این شغل از قسمت‌های جداگانه‌ای از اطلاعات تشکیل شده است که به شرح زیر می‌باشد:</p>
<ul>
<li>شرکت</li>
<li>نوع (full-time, part-time, freelance)</li>
<li>لوگو</li>
<li>آدرس وب (URL)</li>
<li>وضعیت</li>
<li>مکان</li>
<li>دسته (کاربران می‌توانند دسته مورد نظر را از لیست انتخاب کنند)</li>
<li>توضیحات (URL و Email بطور اتوماتیک افزوده می‌شوند)</li>
<li>چگونگی اعمال (URL و Email بطور اتوماتیک افزوده می‌شوند)</li>
<li>عمومیت (آیا امکان انتشار شغل در سایت Affiate میسر است یا خیر)</li>
<li>پست الکترونیک</li>
</ul>
<p>برای ارسال یک شغل نیازی به ایجاد اشتراک نیست. این پروسه تنها در ۲ مرحله صورت می‌گیرد، ابتدا کاربر فرم تشریح شغل را تکمیل می‌کند، سپس پیش نمایش اطلاعات را در صفحه‌ای مشاهده کرده و ان را تائید می‌کند. حتی اگر کاربر اشتراکی نداشته باشد در آدرسی مخصوص می‌تواند شغل ارسالی را ویرایش کند (این امکان بوسیله یک توکن که پس از ایجاد شغل ایجاد می‌شود، محافظت می‌شود)<br />
هر شغل به مدت ۳۰ روز Online می‌ماند (قابل تنظیم در پنل مدیریت B2) کاربر می‌توتند دوباره آن را فعال کند و یا مدت آن را تمدید کند تا بیشتر از ۳۰ روز Online بماند، اما تنها در صورتی که کمتر از ۵ روز به پایان تاریخ انقضا مانده باشد.</p>
<h3>F6: کاربر خود را به عنوان affiliate تعریف می‌کند:</h3>
<p>کاربران جهت استفاده از APIهای Jobeet، باید خود را به عنوان affiliate تعریف کنند و برای اینکار باید اطلاعات زیر را وارد کنند:</p>
<ul>
<li>نام</li>
<li>پست الکترونیک</li>
<li>آدرس وب سایت</li>
</ul>
<p>اشتراک affiliate در قسمت مدیریت تائید می‌شود (B3)، هنگامی که فعال شد، affiliate توکنی را برای استفاده از API بوسیله پست الکترونیک دریافت می‌کند. پس از این مراحل affiliate می‌تواند مشاغل را از یک دسته معتیر انتخاب کند.</p>
<h3>F7: یک affiliate لیست مشاغل جاری را بدست می‌آورد:</h3>
<p>affiliate می‌تواند لیست مشاغل جاری را با فراخوانی API بدست آورد. این لیست می‌تواند در قالب‌های JSON, XML و یا YAML باشد.<br />
لیست هم شامل اطلاعات عمومی معتبر یک شغل می‌باشد. همچنین affiliate می‌تواند برخی از مشاغل و یا تنها دسته‌ای خاص از آنها را نمایش دهد.</p>
<h3>B1: مدیر وبسایت را پیکره‌بندی می‌کند:</h3>
<p>یک مدیر می‌تواند دسته‌های معتبر در سایت را ویرایش کند.</p>
<h3>B2: مدیریت مشاغل بر عهده مدیر است:</h3>
<p>یک مدیر می‌تواند شغلی را ویرایش و یا آن را حذف کند.</p>
<h3>B3: مدیریت affiliateها نیز بر عهده مدیر است:</h3>
<p>مدیر می‌تواند affiliate را ایجاد و یا ان را ویرایش کند. او می‌تواند اشتراک affiliateها را فعال کند و یا انها را ناتوان سازد. هنگامی که مدیر اشتراک affiliate را فعال می‌کند، سیستم یک توکن منحصر به فرد را برای استفاده affiliate ایجاد می‌کند.</p>
<h2>بقیه داستان jobeet را در روز‌های آینده بخوانید</h2>
<p>در برنامه نویسی و توسعه وب، هیچگاه نباید از روز اول به کد‌نویسی پرداخت. ابتدا باید نیاز‌ها را شناسایی و بررسی کنیم. این همان کاری‌است که امروز انجام شد!</p>
<img src="http://www.moshtaghi.ir/weblog/?ak_action=api_record_view&id=347&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.moshtaghi.ir/2009/04/2th-symfony-jobeet/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>آغاز کار با سیمفونی</title>
		<link>http://weblog.moshtaghi.ir/2009/04/starting-with-symfony/</link>
		<comments>http://weblog.moshtaghi.ir/2009/04/starting-with-symfony/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 14:41:00 +0000</pubDate>
		<dc:creator>مهدی</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[jobeet]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.moshtaghi.ir/weblog/?p=319</guid>
		<description><![CDATA[به نظر بنده بهترین مرجع برای شروع سیمفونی (Symfony) همان پروژه Jobeet است که به شما آموزش می‌دهد که چگونه بوسیله این فریم‌ورک در مدت ۲۴ ساعت (روز) یک برنامه تحت وب کار آمد را بصورت کاملاْ حرفه‌ای تولید کنید. البته اشاره به این نکته هم خالی از لطف نیست که این آموزش ۲۴ قسمتی ]]></description>
			<content:encoded><![CDATA[<p>به نظر بنده بهترین مرجع برای شروع سیمفونی (<a title="سایت رسمی سیمفونی" href="http://symfony-project.org/" target="_blank">Symfony</a>) همان پروژه <a href="http://www.symfony-project.org/jobeet/1_2/Propel/en/" target="_blank">Jobeet</a> است که به شما آموزش می‌دهد که چگونه بوسیله این فریم‌ورک در مدت ۲۴ ساعت (روز) یک برنامه تحت وب کار آمد را بصورت کاملاْ حرفه‌ای تولید کنید. البته اشاره به این نکته هم خالی از لطف نیست که این آموزش ۲۴ قسمتی یکی از مزایای سیمفونی در مقابل رقبای قدرتمند خود همچون <a href="http://framework.zend.com/" target="_blank">Zend</a> و <a title="سایت رسمی کیک" href="http://cakephp.org/" target="_blank">CakePHP</a> است. چرا که تولید برنامه‌ای با این قدرت در همان ابتدای راه، نشان دهنده قدرت و در عین حال سادگی سیمفونی می باشد.</p>
<p>در ادامه به ترجمه بخش اول این کتاب (جدای از مقدمه) می‌پردازیم. (طبق معمول ترجمه‌ای پر از اشکال که به عظمت سیمفونی ببخشید)</p>
<h2>امروز چکار می‌کنیم؟</h2>
<p>۲۴ ساعت زمان مناسبی برای توسعه یک برنامه توسط سیمفونی است (در سال صرفه جویی و اصلاح الگوی مصرف، واقعا تا این حد صرفه جویی در زمان کار بسیار پسندیده‌ای است). امروز هیچ کدی نمی‌نویسیم. اما بدون نوشتن حتی یک خط کد، می‌توانیم مزایای استفاده از سیمفونی را تنها با راه اندازی یک پروژه جدید درک کنیم.</p>
<p>هدف امروز ما، راه اندازی محیط توسعه و نمایش صفحه‌ای از برنامه در مرورگر است. اینکار شامل نصب سیمفونی، ایجاد برنامه و تنظیمات وب سرور می‌شود.<span id="more-319"></span></p>
<h2>پیشنیاز‌ها</h2>
<p>قبل از هر چیز محیط توسعه رو چک می‌کنیم. یک وب سرور (ترجیحاْ <a href="http://www.apache.org/" target="_blank">Apache</a>)، یک موتور پایگاه داده (ترجیحاْ <a href="http://mysql.com" target="_blank">MySQL</a>) و <a href="http://php.net" target="_blank">PHP</a> نسخه ۵.۲.۴ و یا جدید‌تر!</p>
<p>در سیمفونی به وفور از خط فرمان استفاده می‌کنیم، پس بهتر است تا از سیستم‌های مبتنی بر Unix (ترجیحاْ لینوکس <a href="http://opensuse.org" target="_blank">OpenSUSE</a> که دلیلش هم بعداْ می‌گم!!!) استفاده کنید. البته ویندوز هم می‌شه ولی نه با این کیفیت!</p>
<p>در ادامه این مباحث بیشتر توجه ما به روی سیمفونی است و فرض را بر این می‌گذاریم که شما اطلاعات خوبی راجع به PHP 5 و OOP یا همون <a href="http://en.wikipedia.org/wiki/Object_oriented" target="_blank">Object Oriented Programming</a> می‌دانید.</p>
<p>برای آشنایی خیلی سریع با برنامه نویسی شی‌گرا <a href="http://www.barnamenevis.org/forum/showthread.php?t=83103" target="_blank">این تاپیک </a>را مطالعه کنید.</p>
<h2>نصب سیمفونی</h2>
<p>ابتدا برای میزبانی فایل‌های مرتبط با پروژه Jobeet یک پوشه می‌سازیم و بهتر است این‌ کار را توسط خط فرمان انجام دهیم.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>sfprojects<span style="color: #000000; font-weight: bold;">/</span>jobeet
$ <span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>sfprojects<span style="color: #000000; font-weight: bold;">/</span>jobeet</pre></div></div>

<p>حالا یک پوشه هم برای فایل‌های کتابخانه‌ای سیمفونی می‌سازیم</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> lib<span style="color: #000000; font-weight: bold;">/</span>vendor</pre></div></div>

<p>صفحه نصب در سایت رسمی پروژه تمام نسخه‌های مجاز رو لیست و مقایسه کرده. این آموزش نیز برای ورژن ۱.۲ نوشته شده است. به صفحه نصب این نسخه بروید و در قسمت زیرین Source Download، آرشیوی از فرمت‌های tgz و یا zip رو می‌تونید پیدا کنید. آرشیو را دانلود کرده و در پوشه‌ای که به تازگی ایجاد کردید قرار دهید و سپس آن را از حالت فشرده خارج کنید و البته باز هم سعی کنید اینکار را با استفاده از Terminal انجام دهید!</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #7a0874; font-weight: bold;">cd</span> lib<span style="color: #000000; font-weight: bold;">/</span>vendor
$ <span style="color: #c20cb9; font-weight: bold;">tar</span> zxpf symfony-1.2.2.tgz
$ <span style="color: #c20cb9; font-weight: bold;">mv</span> symfony-1.2.2 symfony
$ <span style="color: #c20cb9; font-weight: bold;">rm</span> symfony-1.2.2.tgz</pre></div></div>

<p>از آنجایی که پیکر‌بندی PHP بواسطه وجود نسخه‌های مختلف بسیار متفاوت است، ما نیاز به بررسی پیکره‌بندی PHP داریم تا از وجود حداقل‌ها برای سازگاری با سیمفونی آگاه شویم.</p>
<p>اسکریپت configuration checker رو از خط فرمان اجرا می‌کنیم.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #7a0874; font-weight: bold;">cd</span> ..<span style="color: #000000; font-weight: bold;">/</span>..
$ php lib<span style="color: #000000; font-weight: bold;">/</span>vendor<span style="color: #000000; font-weight: bold;">/</span>symfony<span style="color: #000000; font-weight: bold;">/</span>data<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>check_configuration.php</pre></div></div>

<p>اگر مشکلی باشد در خروجی به شما تذکر خواهد داد و راه حل رفع ان را نیز به شما می‌گوید. همچنین می‌توان این آزمایش را بدون استفاده از خط فرمان در مرورگر اجرا کرد. فایل اسکریپت رو در شاخه ریشه وب کپی کنید و به آدرس مربوطه بروید و هرگز فراموش نکنید که بعد از پاک کردن فایل رو پاک کنید.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">rm</span> web<span style="color: #000000; font-weight: bold;">/</span>check_configuration.php</pre></div></div>

<div id="attachment_79" class="wp-caption aligncenter" style="width: 310px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/1sec1_configuration_check.png"><img class="size-medium wp-image-79" title="configuration checker" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/1sec1_configuration_check-300x244.png" alt="1sec1_configuration_check" width="300" height="244" /></a><p class="wp-caption-text">تصویر شماره ۱-۱ / configuration checker</p></div>
<p>اگر در خروجی خطایی داده نشد نشان دهنده نصب درست سیمفونی است. شما می‌توانید بوسیله خط فرمان ورژن سیمفونی را مشاهده نمائید.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php lib<span style="color: #000000; font-weight: bold;">/</span>vendor<span style="color: #000000; font-weight: bold;">/</span>symfony<span style="color: #000000; font-weight: bold;">/</span>data<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>symfony <span style="color: #660033;">-V</span></pre></div></div>

<p>اگر شما هم مثل بنده مشتاقی هستید، که بعید می‌دونم!!! اما  احتمالاْ مشتاق هستید که در رابطه با ابزار‌هایی که سیمفونی در خط فرمان فراهم کرده اطلاعاتی کسب کنید. کلمه symfony را در خط فرمان تایپ کنید تا لیستی از آپشن‌ها و وظایف رو مشاهده کنید.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php lib<span style="color: #000000; font-weight: bold;">/</span>vendor<span style="color: #000000; font-weight: bold;">/</span>symfony<span style="color: #000000; font-weight: bold;">/</span>data<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>symfony</pre></div></div>

<p>خط فرمان سیمفونی بهترین دوست شما است، زیرا بهترین تسهیلات رو برای شما مهیا می‌کند و قابلیت‌های شما را در فعالیت‌های روزانه همچون پاک کردن Cach، ایجاد کد‌ها و &#8230; بهبود می‌بخشد.</p>
<h2>راه‌اندازی پروژه</h2>
<p>در سیمفونی، Applicationها اشتراک همان مدل‌های داده هستند که در پروژه‌ها جمع‌آوری می‌شوند. برای Jobeet ما دو Application داریم: یکی Frontend و دیگری Backend.</p>
<h2>ایجاد پروژه</h2>
<p>فرمان <code>generate:project</code> را از پوشه Jobeet اجرا کنید که در حقیقت وظیفه ساخت پروژه را دارد.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php lib<span style="color: #000000; font-weight: bold;">/</span>vendor<span style="color: #000000; font-weight: bold;">/</span>symfony<span style="color: #000000; font-weight: bold;">/</span>data<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>symfony generate:project jobeet</pre></div></div>

<p>این دستور وظیفه ایجاد ساختار پیش‌فرض فایل‌ها و پوشه‌ها را به عهده دارد.</p>
<table class="doc_table" border="0">
<thead>
<tr>
<th>پوشه</th>
<th>شرح</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>apps/</code></td>
<td>میزبانی تمامی Applicationهای پروژه</td>
</tr>
<tr>
<td><code>cache/</code></td>
<td>فایل‌های Cache شده از فریم‌ورک</td>
</tr>
<tr>
<td><code>config/</code></td>
<td>فایل‌های پیکره‌بندی پروژه</td>
</tr>
<tr>
<td><code>lib/</code></td>
<td>کتابخانه‌ها و کلاس‌های پروژه</td>
</tr>
<tr>
<td><code>log/</code></td>
<td>فایل‌های log فریم‌ورک</td>
</tr>
<tr>
<td><code>plugins/</code></td>
<td>افزونه‌های نصب شده</td>
</tr>
<tr>
<td><code>test/</code></td>
<td>دستگاه آزمایش اساسی فایل‌ها</td>
</tr>
<tr>
<td><code>web/</code></td>
<td>پوشه ریشه وب (در پایین می‌بینیم)</td>
</tr>
</tbody>
</table>
<blockquote><p><strong>نکته</strong> : چرا سیمفونی فایل‌های زیاد تولید می‌کند؟ یکی از مزایای استفاده از یک فریم‌ورک <strong>full-stack</strong> این است که توسعه شما را استاندارد می‌کند. هر توسعه دهنده ای با دانسته‌هایی اندک از سیمفونی، میتواند از پروژه‌های سیمفونی حمایت کند. تنها با چند دقیقه وقت گذاشتن می‌شه داخل کد‌ها رفت، حفره‌های آنها را گرفت و یا ویژگی‌های جدیدی رو به انها افزود.</p></blockquote>
<p>وظیفه <code>generate:project</code> ساخت یک میان‌بر در شاخه اصلی پروژه است تا هنگام اجرای وظایف (Task) کمترین تعداد کاراکتر را تایپ کنید.</p>
<p>همچنین از این به بعد، بجای استفاده بجای استفاده از مسیر‌های کامل و صحیح به Applicationهای سیمفونی از میان‌برها استفاده می‌کنیم.</p>
<h2>ایجاد Application</h2>
<p>حالا نمای جلوی برنامه را بوسیله دستور <code>generate:app</code> ایجاد می‌کنیم.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php symfony generate:app <span style="color: #660033;">--escaping-strategy</span>=on <span style="color: #660033;">--csrf-secret</span>=UniqueSecret frontend</pre></div></div>

<p>نکته :به دلیل اجرایی بودن فایل‌های میان‌بر سیمفونی، از این پس کاربران unix می‌توانند بجای تمام رخداد‌های <code>php symfony</code> از <code>./symfony</code> استفاده کنند.</p>
<p>اساس یک application روی نام است، زیرا یک شناسه است، وظیفه <code>generate:app</code> ایجاد ساختار پیش‌فرض پوشه‌هایی است که برنامه نیاز دارد و تحت پوشه <code>apps/frontend</code> قرار می‌گیرند.</p>
<table border="0">
<thead>
<tr>
<th>پوشه</th>
<th>شرح</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>config/</code></td>
<td>فایل‌های پیکره‌بندی application</td>
</tr>
<tr>
<td><code>lib/</code></td>
<td>کتابخانه‌ها و کلاس‌های application</td>
</tr>
<tr>
<td><code>modules/</code></td>
<td>کد‌های application (توجه به MVC)</td>
</tr>
<tr>
<td><code>templates/</code></td>
<td>فایل‌های سراسری قالب</td>
</tr>
</tbody>
</table>
<blockquote><p><strong>نکته</strong> : تمام دستورات سیمفونی باید در پوشه ریشه پروژه اجرا شوند، مگر اینکه بطور صریح طور دیگری اعلام کنند.</p></blockquote>
<p>علاوه بر اینها به هنگام فراخوانی وظیفه <code>generate:app</code> از دو خصیصه امنیتی مرتبط عبور می‌کنیم.</p>
<ul>
<li> &#8211;escaping-strategy : فعال کردن فرار خروجی برای جلوگیری از حملات XSS</li>
<li> &#8211;csrf-secret : فعال کردن اجازه ورود به نشست‌ها در فرم‌ها برای جلوگیری از حملات SCRF</li>
</ul>
<p>با اعمال این دو خصیصه اختیاری به وظیفه، می‌توانیم آینده توسعه خودمان را برای بیشتر از ۲ آسیب‌پذیری رایج در وب امن کنیم. درسته! سیمفونی بطور خودکار اقدامات امنیتی را از طرف ما انجام می‌دهد.</p>
<blockquote><p><strong>یادداشت</strong> : اگر در رابطه با XSS و CSRF چیزی نمی‌دانید، وقتی را به یادگیری درباره این دو آسیب‌پذیری امنیتی اختصاص دهید.</p></blockquote>
<h2>مسیر سیمفونی</h2>
<p>شما می‌توانید نسخه استفاده شده برای پروژه را با استفاده از دستور زیر بدست آورید.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ php symfony <span style="color: #660033;">-V</span>
or
$ symfony <span style="color: #660033;">-V</span></pre></div></div>

<p>این دستور مسیر پوشه نصب سیمفونی را نیز نمایش می‌دهد که می‌توان آن را در آدرس  <code>config/ProjectConfiguration.class.php</code> پیدا کرد:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// config/ProjectConfiguration.class.php</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'/Users/mehdi/work/symfony/dev/1.2/lib/autoload/sfCoreAutoload.class.php'</span><span style="color: #339933;">;</span></pre></div></div>

<p>برای بهبود قابلیت حمل، مسیر مطلق را با یک مسیر نسبی تعویض می‌کنیم.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// config/ProjectConfiguration.class.php</span>
<span style="color: #b1b100;">require_once</span> <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php'</span><span style="color: #339933;">;</span></pre></div></div>

<p>حالا شما می‌توانید پروژه را بروی هر سیستمی انتقال دهید و اون به درستی کار کند.</p>
<h2>محیط</h2>
<p>اگر به پوشه<code> /web</code> نگاه کنید، دو  فایل PHP را در آن پیدا می‌کنید: <code>index.php‌</code> و <code>frontend_dev.php. </code>این فایل‌ها برای فراخوانی front controller هستند: تمام درخواست‌ها به application  بواسطه آنها ساخته شده‌اند.</p>
<p>اما چرا دو عدد front controller داریم، در حالی که تنها یک application ساخته‌ایم؟!</p>
<p>هر دو فایل، همان application را نمایش می‌دهند اما برای محیط‌های متفاوت. زمانی که شما application را توسعه می‌دهید، نیاز به یک محیط توسعه دارید، مگر توسعه شما مستقیماْ بروی سرور باشد.</p>
<p>Development environment : این محیطی است که توسعه دهندگان بهنگام کار بروی برنامه‌ها برای اضافه کردن خصوصیات و رفع حفره‌ها از ان استفاده می‌کنند.</p>
<p>Test environment : این محیط در آزمایش‌های خودکار مورد استفاده قرار می‌گیرد.</p>
<p>Staging environment : این محیز برای استفاده مشتری (کارفرما) برای امتحان و گزارش حفره‌ها و قابلیت‌های فراموش شده است.</p>
<p>Production environment : این محیط هم اخر کار است و برای ارائه نهایی است.</p>
<p>اما چرا تهیه محیط‌های مختلف؟ برای مثال در محیط‌ توسعه برای راحتی در کار اشکال زدایی به log شدن تمام جزئیات درخواست‌ نیاز است. اما سیستم Cache باید غیر فعال باشد تا تمامی  تغییرات ایجاد شده در کد اعمال شوند. بنابراین  بهینه سازی محیط توسعه برای اینکار ضروری است. بهترین مثال زمانی است که یک مشکل خاص در برنامه رخ می‌دهد. برای کمک به توسعه دهنده سیمفونی این مشکل خاص رو بهمراه تمامی اطلاعاتش در رابطه با درخواست‌ جاری، در مرورگر نمایش می‌دهد.</p>
<div id="attachment_79" class="wp-caption aligncenter" style="width: 310px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/1sec2_exception_dev.png"><img class="size-medium wp-image-79" title="Exception dev" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/1sec2_exception_dev-300x184.png" alt="1sec1_configuration_check" width="300" height="184" /></a><p class="wp-caption-text">تصویر شماره ۲-۱ / Exception dev</p></div>
<p>اما در محیط ارائه Cache فعال است و به خوبی کار می‌کند. برنامه نیز پیغام‌های خطا را بجای اتفاق‌های خاص نمایش می‌دهد. بنابراین محیط ارائه برای نمایش و فعالیت کاربران بهینه شده است.</p>
<div id="attachment_79" class="wp-caption aligncenter" style="width: 310px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/1sec3_exception_prod.png"><img class="size-medium wp-image-79" title="Exception prod" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/1sec3_exception_prod-300x154.png" alt="1sec1_configuration_check" width="300" height="154" /></a><p class="wp-caption-text">تصویر شماره ۳-۱ / Exception prod</p></div>
<p>محیط‌های سیمفونی دارای تنظیمات جداگانه‌ای هستند. فریم‌ورک سیمفونی بهمراه این سه می‌آید: dev، test و prod. در روز ۲۲ (قسمت ۲۲ آموزش) چگونگی ساخت یک محیط جدید رو فرا می‌گیرید و البته محیطstaging .</p>
<p>اگر فایل front controller را باز کنید، محتویات زیر را مشاهده خواهید کرد که برای تنظیمات محیط است.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// web/index.php</span>
<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>?php
&nbsp;
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/../config/ProjectConfiguration.class.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$configuration</span> <span style="color: #339933;">=</span> ProjectConfiguration<span style="color: #339933;">::</span><span style="color: #004000;">getApplicationConfiguration</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'frontend'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'prod'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
sfContext<span style="color: #339933;">::</span><span style="color: #004000;">createInstance</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$configuration</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>dispatch<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<blockquote><p><strong>یادداشت</strong> : تعیین یک محیط برای سیمفونی حتی از ایجاد یک front controller هم آسان‌تر است. در آینده می‌بینیم که چطور می‌توان تنظیمات یک محیط را تغییر داد.</p></blockquote>
<h2>راه‌اندازی وب سرور : شیوه اشتباه</h2>
<p>در بخش قبلی، پوشه‌ای برای میزبانی Jobeet ایجاد کردیم. اگر شما این پوشه را در مکانی تحت وب سرور سیستم خود ایجاد کردید، در مرورگر به پروژه خود دسترسی دارید.</p>
<p>درسته! چون پیکره‌بندی وجود ندارد راه‌اندازی خیلی سریع انجام شد. اما تلاش برای دسترسی به فایل <code>config/databases.yml</code> در مرورگر شما برای درک نتایج بد این تنبلی.اگر کاربران بدونند که وبسایت شما با سیمفونی توسعه پیدا کرده، می‌توانند به بسیاری از فایل‌های مهم دسترسی پیدا کنند.</p>
<p>هرگز اینکار را در سرور انجام ندهید و بخش بعدی رو برای یادگیری چگونگی راه‌اندازی وب سرور مطالعه کنید.</p>
<h2>راه‌اندازی وب سرور : شیوه مطمئن</h2>
<p>بهترین‌ کار این است که تنها فایل‌هایی که باید توسط مرورگر دسترسی داشته باشند همچون فایل‌های سبک‌نامه، جاوا و تصاویر را در پوشه اصلی قرار داده که البته بهتر است بطور پیشفرض در پوشه<code> /web</code> قرار دهیم.</p>
<p>اگر نگاهی به این پوشه انداخته باشید زیر پوشه‌هایی رو می‌بینید که دارایی آنها، فایل‌ها (سبک‌نامه، تصاویر و &#8230;) و دو فایل front controller هستند.front controllerها تنها فایل‌های PHP هستند که نیاز دارند تا در پوشه ریشه وب سرور قرار بگیرند. همه فایل‌های دیگر PHP می‌توانند از دید مرورگر مخفی شوند. که این ایده خوبی از لحاظ امنیتی است.</p>
<h2>پیکره‌بندی وب سرور</h2>
<p>حالا زمان ان رسیده تا پیکره‌بندی Apache را تغییر دهیم.</p>
<p>فایل پیکره‌بندی <code>httpd.conf</code> را باز کرده و این کد‌ها را در خط اخر ان اضافه کنید.</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #adadad; font-style: italic;"># Be sure to only have this line once in your configuration</span>
<span style="color: #00007f;">NameVirtualHost</span> 127.0.0.1:<span style="color: #ff0000;">8080</span>
&nbsp;
<span style="color: #adadad; font-style: italic;"># This is the configuration for Jobeet</span>
<span style="color: #00007f;">Listen</span> 127.0.0.1:<span style="color: #ff0000;">8080</span>
&nbsp;
&amp;lt;VirtualHost 127.0.0.1:<span style="color: #ff0000;">8080</span>&amp;gt;
<span style="color: #00007f;">DocumentRoot</span> <span style="color: #7f007f;">&quot;/home/sfprojects/jobeet/web&quot;</span>
<span style="color: #00007f;">DirectoryIndex</span> index.php
&amp;lt;Directory <span style="color: #7f007f;">&quot;/home/sfprojects/jobeet/web&quot;</span>&amp;gt;
<span style="color: #00007f;">AllowOverride</span> <span style="color: #00007f;">All</span>
<span style="color: #00007f;">Allow</span> <span style="color: #00007f;">from</span> <span style="color: #00007f;">All</span>
&amp;lt;/Directory&amp;gt;
&nbsp;
<span style="color: #00007f;">Alias</span> /sf /home/sfprojects/jobeet/lib/vendor/symfony/data/web/sf
&amp;lt;Directory <span style="color: #7f007f;">&quot;/home/sfprojects/jobeet/lib/vendor/symfony/data/web/sf&quot;</span>&amp;gt;
<span style="color: #00007f;">AllowOverride</span> <span style="color: #00007f;">All</span>
<span style="color: #00007f;">Allow</span> <span style="color: #00007f;">from</span> <span style="color: #00007f;">All</span>
&amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;</pre></div></div>

<p>این پیکره‌بندی، Jobeet را در آدرس <code>http://localhost:8080/ </code>قابل دسترس می‌کند</p>
<p>شما می‌توانید این عدد را با هر عدد دیگری تغییر دهید. اما بهتر است از اعداد بزرگتر از ۱۰۲۴ استفاده کنید. زیرا این اعداد نیازی به اجازه مدیر سیستم ندارند.</p>
<h2>آزمایش پیکره‌بندی جدید</h2>
<p>Apache را دوباره راه‌اندازی کنید (restart). دسترسی به jobeet را با استفاده از آدرس بالا امتحان کنید.</p>
<div id="attachment_79" class="wp-caption aligncenter" style="width: 310px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/1sec4_congratulations.png"><img class="size-medium wp-image-79" title="congratulations" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/1sec4_congratulations-300x211.png" alt="1sec1_configuration_check" width="300" height="211" /></a><p class="wp-caption-text">تصویر شماره ۴-۱ / Congratulations</p></div>
<blockquote><p><strong>یادداشت</strong> : اگر ماژول mod-rewrite شما در apache فعال باشد می‌توانید عبارت index.php را از انتهای آدرس حذف کنید. اینکار به برکت قوائد دوباره نویسی پیکره‌بندی شده در فایل /web/.htaccess امکان پذیر است.</p></blockquote>
<p>همچنین باید دسترسی برنامه را در محیط توسعه امتحان کنیم.</p>
<p><code>http://jobeet.localhost/frontend_dev.php/</code></p>
<p>نوار ابزار عیب‌یابی را باید در گوشه بالا سمت راست مشاهده کنید که شامل آیکون کوچک SF که نام اختصاری سیمفونی است می‌باشد.</p>
<div id="attachment_79" class="wp-caption aligncenter" style="width: 310px"><a href="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/1sec5_web_debug_toolbar.png"><img class="size-medium wp-image-79" title="web_debug_toolbar" src="http://moshtaghi.ir/weblog/wp-content/uploads/2009/04/1sec5_web_debug_toolbar-300x211.png" alt="1sec1_configuration_check" width="300" height="211" /></a><p class="wp-caption-text">تصویر شماره ۵-۱ / Web debug toolbar</p></div>
<p>نوار ابزار فوق در تمام صفحات در محیط توسعه حاضر است و دسترسی به اطلاعات زیادی را بوسیله کلیک بروی سایر تب‌ها به شما می‌دهد. اطلاعاتی همچون پیکر بندی فعلی برنامه، وقایع درخواست جاری، دستورات SQL اجرا شده در موتور پایگاه داده، اطلاعات حافظه و اطلاعات زمان.</p>
<h2>Subversion</h2>
<p>بهترین کار این است که هنگام توسعه یک برنامه از SVN استفاده کنیم.</p>
<p>برخی از مزایای استفاده از SVN :</p>
<p>با اطمینان کار کردن</p>
<ul>
<li> برگشت به نسخه قبلی در صورت شکست تغییرات ایجاد شده</li>
<li> امکان کار کردن موثر و واقعی بیشتر از چند نفر بر روی یک پروژه</li>
<li> دسترسی به تمامی نسخه‌های منتشر شده پی در پی</li>
</ul>
<p>در این بخش به شرح چگونگی کار کردن با SVN بوسیله سیمفونی می‌پردازیم. اگر شما از هر ابزار کنترل کد دیگری استفاده می‌کنید، توضیح در مورد چگونگی SVN بسیار راحت خواهد شد.</p>
<p>تصور را بر این می‌گذاریم که شما به یک سرور subversion دسترسی دارید و می‌توانید بوسیله http با اون کار کنید.</p>
<p>نکته : اگر سرور subversion در دسترس ندارید، می‌توانید به رایگان در google code یک مخزن ایجاد کنید و یا عبارت free subversion را در google جستجو کنید و &#8230;</p>
<p>ابتدا مخزن پروژه Jobeet را ایجاد می‌کنیم.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">svnadmin</span> create <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>jobeet<span style="color: #000000; font-weight: bold;">/</span>repository</pre></div></div>

<p>ساختار اصلی پوشه‌ها را در سیستم ایجاد می‌کنیم.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">svn</span> <span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;created default directory structure&quot;</span> http:<span style="color: #000000; font-weight: bold;">//</span>svn.example.com<span style="color: #000000; font-weight: bold;">/</span>jobeet<span style="color: #000000; font-weight: bold;">/</span>trunk http:<span style="color: #000000; font-weight: bold;">//</span>svn.example.com<span style="color: #000000; font-weight: bold;">/</span>jobeet<span style="color: #000000; font-weight: bold;">/</span>tags http:<span style="color: #000000; font-weight: bold;">//</span>svn.example.com<span style="color: #000000; font-weight: bold;">/</span>jobeet<span style="color: #000000; font-weight: bold;">/</span>branches</pre></div></div>

<p>و پوشه خالی trunk را بررسی می‌کنیم.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>sfprojects<span style="color: #000000; font-weight: bold;">/</span>jobeet
$ <span style="color: #c20cb9; font-weight: bold;">svn</span> <span style="color: #c20cb9; font-weight: bold;">co</span> http:<span style="color: #000000; font-weight: bold;">//</span>svn.example.com<span style="color: #000000; font-weight: bold;">/</span>jobeet<span style="color: #000000; font-weight: bold;">/</span>trunk<span style="color: #000000; font-weight: bold;">/</span> .</pre></div></div>

<p>سپس محتویات پوشه<code> /cache</code> و<code> /log</code> را پاک می‌کنیم، زیرا نیازی به درج انها در مخزن نداریم.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> cache<span style="color: #000000; font-weight: bold;">/*</span> log<span style="color: #000000; font-weight: bold;">/*</span></pre></div></div>

<p>حالا از دسترسی‌های پوشه‌های <code> /cache</code> و <code> /log</code> اطمینان حاصل می‌کنیم تا سرویس دهنده وب بتواند در آنها بنویسد.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">chmod</span> <span style="color: #000000;">777</span> cache<span style="color: #000000; font-weight: bold;">/</span> log<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>حالا تمامی فایل‌ها و پوشه‌ها را وارد می‌کنیم.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">svn</span> add <span style="color: #000000; font-weight: bold;">*</span></pre></div></div>

<p>از آنجایی که نیازی به فایل‌های موجود در پوشه‌های <code> /cache</code> و <code> /log</code> نداریم باید آنها را در ignore list قرار دهیم.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">svn</span> propedit <span style="color: #c20cb9; font-weight: bold;">svn</span>:ignore cache</pre></div></div>

<p>ویرایش‌گر متن پیشفرض برای SVN باید راه افتاده باشد. Subversion باید تمامی محتوای موجود در این پوشه را ignore کند.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">*</span></pre></div></div>

<p>ذخیره کنید و خارج شوید. شما موفق شدید.</p>
<p>این مراحل را برای پوشه log تکرار کنید.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">svn</span> propedit <span style="color: #c20cb9; font-weight: bold;">svn</span>:ignore log</pre></div></div>

<p>و وارد کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">*</span></pre></div></div>

<p>در نهایت، این تغییرات رو در مخزن اعمال کنید</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">svn</span> import <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;made the initial import&quot;</span> . http:<span style="color: #000000; font-weight: bold;">//</span>svn.example.com<span style="color: #000000; font-weight: bold;">/</span>jobeet<span style="color: #000000; font-weight: bold;">/</span>trunk</pre></div></div>

<h2>فردا (بخش دوم) همدیگر را خواهیم دید</h2>
<p>وقت امروز تمام شد. با این حال حتی اگر صحبت کردن در رابطه با سیمفونی را آغاز نکردیم، اما یک محیط توسعه پایدار داریم، در رابطه با بهترین شیوه‌های توسعه وب بحث کردیم و هم اکنون برای کد نویسی آماده شده‌ایم.</p>
<p>فردا مشخص می‌کنیم که چه برنامه‌ای را خواهیم نوشت و درباره ملزوماتی که برای اتمام پروژه در طول مدت آموزش به آن نیاز داریم بحث خواهیم کرد.</p>
<blockquote><p><strong>یادداشت</strong> : اگر می‌خواهید کد امروز و یا هر روز دیگری را بررسی کنید، کدها بصورت روز به روز در مخازن رسمی Jobeet یافت می‌شوند.<code>(http://svn.jobeet.org/propel)</code></p>
<p>برای مثال شما می‌توانید با استفاده از تگ <code>release_day_01</code> کد‌های امروز را دریافت کنید.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">svn</span> <span style="color: #c20cb9; font-weight: bold;">co</span> http:<span style="color: #000000; font-weight: bold;">//</span>svn.jobeet.org<span style="color: #000000; font-weight: bold;">/</span>propel<span style="color: #000000; font-weight: bold;">/</span>tags<span style="color: #000000; font-weight: bold;">/</span>release_day_01<span style="color: #000000; font-weight: bold;">/</span> jobeet<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

</blockquote>
<img src="http://www.moshtaghi.ir/weblog/?ak_action=api_record_view&id=319&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.moshtaghi.ir/2009/04/starting-with-symfony/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>
