آموزش ساخت افزونه وردپرس - قسمت دوم
خب امیدوارم قسمت اول آموزش رو خونده باشین ، حسابی شاد و شنگول باشین ، خشاب هارو پر کرده باشین و میریم سراغ قسمت دوم .
در این قسمت ما بصورت عملی شروع میکنیم یک افزونه بنویسیم .
خب به نظرم رسید یک افزونه لینک های روزانه بنویسیم بهتر باشه . و کمکم طی چند مرحله دیگه با کمک و نظر شما کاملش کنیم و انشاالله استفاده کنیم .
در ادامه با من باشید.اولین قدم در ساخت افزونه وردپرس اینه که بدونی چی میخوای؟ what do you want؟
خب ما یک افزونه میخوایم که لینک های روزانه رو توش بنویسیم و در سایت نمایش بدیم ، این افزونه باید تعداد کلیک ها رو شمارش کنه ، همچنین یک تابع برای استفاده در قالب و یک ابزارک براش بنویسیم که توی ابزارک یه سری تنظیمات انجام بدیم مثلاً تعداد لینکها ، این افزونه باید توی قسمت مدیریت دارای سه صفحه برای نمایش لینک ها ، افزودن لینک و ویرایش لینک باشه .
خب بیایید شروع کنیم!
اینجا نقطه حساس برنامه است ، یعنی انتخاب اسم افزونه ، حساسه دیگه چرا میخندی؟ خب برای جلوگیری از هرگونه سو استفاده احتمالی اسم افزونه رو میذاریم reza-dailylink
به پوشه plugins واقع در wp-content برید و یک پوشه به اسم reza-dailylink ایجاد کنید ، محتوای پوشه هم یک فایل reza-dailylink.php بذارید ، از این به بعد تمامی کار ما با همین فایل هست .
تعریف افزونه به وردپرس
خب فایل reza-dailylink.php رو با برنامه Notepad++ Home ++Notepad باز کنید و 10 خط اول اون رو با دستورات زیر پر کنید ، یادتون Encoding رو روی UTF-8 Without BOM بذارید . همچنین دقیق خط ها رو اونطور که من میگم پر کنید تا وقتی مثلاً میگم برید خط 25 بدونید چه دستوری میگم! توی سورس خط شروع رو با #@ نشون میدم .
خب پس این ده خط رو کپی کنید و جیکتون در نیاد 
کد:
<?php
/*
Plugin Name: Reza Daily Link
Plugin URI: http://www.rezaonline.net/blog/
Description: افزونه لینک های روزانه
Version: 1.0
Author: رضا شیخله
Author URI: http://www.rezaonline.net/blog
License: GPL2
*/
الان برید توی افزونه ها، باید افزونه Reza Daily Link رو مشاهده کنید .
تعریف ثابت ها و اعتبار سنجی دسترسی مستقیم به فایل
دستورات زیر رو کپی کنید تاتوضیح بدم.
کد:
#@11
#
# برای جلوگیری از دسترسی مستقیم به فایل
#
defined('ABSPATH') or die('<h3>Access denied!');
#
# تعریف ثوابت مورد نیاز
#
define ('reza_dailylink_ver','1.0');
define ('reza_dailylink_dir', dirname(__FILE__));
define ('reza_dailylink_uri', get_option('siteurl').'/wp-content/plugins/reza-dailylink');
خط 15 چک کردیم که اگر ثابت ABSPATH تعریف نشده خطا بده ! خب حالا میپرسید این به چه دردی میخوره؟! خب ببنید افزونه های وردپرس ، توسط خود وردپرس باید اینکلود بشن و استفاده بشن ، الان اگر به آدرس site.ir/wp-content/plugins/reza-dailylink/reza-dailylink.php برید ، قطعاً توسط این دستور خطا براش شما ایجاد میشه .
متاسفانه خیلی ها این مورد رو رعایت نمیکنن .
خب توی خطهای 19 ، 20 ، 21 سه تا ثابت تعریف کردیم اولیش ورژن افزونه ، دومیشه دایرکتوری افزونه و سومیش uri پوشه افزونه هست ، مثلاً گاهی اوقات میخوایم از عکسی ، چیزی توی پوشه افزونه استفاده کنیم باید آدرسش رو با این بدیم.
فعالسازی افزونه و انجام تغییرات
کد زیر رو عیناً اضافه کنید تا توضیحات رو بدم خدمتتون
کد:
#@22
#
# انجام عملیات در هنگام فعال سازی افزونه
#
register_activation_hook(__FILE__,'reza_dailylink_install');
function reza_dailylink_install()
{
global $wpdb;
$tbl = $wpdb->prefix."reza_dailylink";
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
// Creat table
$creattbl = "CREATE TABLE IF NOT EXISTS $tbl
(
`id` INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`title` VARCHAR( 400 ) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL ,
`addr` VARCHAR( 400 ) CHARACTER SET utf8 COLLATE utf8_persian_ci NOT NULL ,
`des` TINYTEXT NULL ,
`click` INT( 10 ) NOT NULL DEFAULT '0',
INDEX ( `click` )
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_bin;";
dbDelta($creattbl);
// Other Options
add_option("reza_dailylink_links", 10, '', 'yes');
add_option("reza_dailylink_show_visit", 1 , '', 'yes');
}
خب اگه آموزش قبلی رو خونده باشید باید بدونید که تابع reza_dailylink_install با فعال کردن افزونه صدا زده میشه .
ما برای افزونه به یک جدول مجزا نیاز داریم که اونو با فعالکردن افزونه میسازیم
این افزونه دارای 5 فیلد هست ، فیلد id برای شناسه هر لینک که بعداً استفاده میکنیم ، فیلد title عنوان لینک ، فیلد addr برای قرار گیری لینک ، فیلد des برای توضیحات و فیلد click برای نمایش تعداد کلیک ها .
خب برای کوئری نوشتن ساخت تیبل نیاز به تابع dbDelta هست که اون توی wp-admin/includes/upgrade.php
همچنین در کل وردپرس آبجکت wpdb کار کوئری زدن به دیتابیس رو انجام میده پس ما باید توی تابع ازش استفاده کنیم لذا اونو global تعریف میکنیم .
یه چیز دیگه ام دو تا آپشن میخوایم یکیش برای تعداد لینک های نمایشی ، یکی هم برای اینکه مدیر انتخاب کنه که تعداد بازدید ها نشون داده بشه یا نشه
این دو تا آپشن رو هم اینجا تعریف میکنیم
غیرفعالسازی افزونه و انجام تغییرات
کدهای زیر رو اضافه کنید
کد:
#@47
#
# انجام عملیات در هنگام غیرفعال سازی افزونه
#
register_deactivation_hook( __FILE__, 'reza_dailylink_remove' );
function reza_dailylink_remove()
{
// no action
}
خب در هنگام غیرفعالسازی افزونه ، تابع reza_dailylink_remove صدا زده میشه و اونطور که میبینید این تابع هیچ کاری نمیکنه !
در حقیقت من میتونستم تمامی رکوردها رو حذف کنم اما اینکار اینجا جایز نیست (اسلام اینو میگه 
دلیلشم این که شاید یکی 200 تا لینک گذاشته با غیرفعال کردن افزونه همیش میپره .
قابلیت حذف و رست کردن جدول بعداً برای افزونه در نظر گرفته میشه
افزودن منوهای مدیریتی
دستورات زیر رو بنویسید در ادامه
کد:
#@56
#
# افزودن منوهای مدیریت وردپرس
#
if ( is_admin() )
{
add_action('admin_menu', 'reza_dailylink_admin_menu');
function reza_dailylink_admin_menu()
{
add_menu_page('لینک های روزانه', 'لینک های روزانه', 'administrator','reza_dailylink_main_html', 'reza_dailylink_main_html');
add_submenu_page('reza_dailylink_main_html','افزودن لینک',"افزودن لینک", 'administrator','reza_dailylink_add_html','reza_dailylink_add_html');
add_submenu_page('reza_dailylink_main_html','ویرایش لینک',"ویرایش لینک", 'administrator','reza_dailylink_edit_html','reza_dailylink_edit_html');
}
تابع is_admin چیکار میکنه؟ آفرین درست گفتین ، چک میکنه که کسی که لاگین کرده مدیریه یا نه اگه مدیره که منو ها اضافه بشه اگرم نه که ...
میاییم پائین ، یک اکشن داریم به admin_menu برای نصب منو های مدیریتی
ما سه تا صفحه میخوایم ، یکیش برای نمایش تمامی لینک ها ، یکیش برای افزودن لینک ، یکیشم برای ویرایش لینک ها
خب من منو اصلی رو ، لینک های روزانه گذاشتم و بقیه رو بصورت زیر منو نشون دادم .
طرز کار این توابع رو بلدین دیگه ؟! اگه نه آموزش قبلی
خب باید الان ما بعد از اینا سه تابع تعریف کنیم برای نمایش محتویات برگه هایی که منو ها هستن .
یعنی روی منو ها کلیک کردن چی نشون بده .
منوی لینک های روزانه رو میبینید؟ تابع مربوط به لینک های روزانه میشه reza_dailylink_main_html
خب بریم واسه ادامه
تعریف محتویات صفحه منوی لینک های روزانه و نمایش تمامی لینک ها
خب دستورات زیر رو باز اضافه کنید (لطفاً کپی نکنید خودتون بنویسید)
کد:
#@70
/*reza_dailylink_main_html*/
function reza_dailylink_main_html()
{
global $wpdb;
$tbl = $wpdb->prefix . "reza_dailylink";
$wpdb->show_errors();
//start html
$result = $wpdb->get_results( "SELECT * FROM `$tbl` ORDER BY id DESC");
echo '<h3>لینکها :</h3>';
foreach($result as $row) :
?>
شناسه : <?php echo $row->id ;?> | عنوان :<?php echo $row->title ;?> | آدرس : <?php echo $row->addr;?> | توضیحات : <?php echo nl2br($row->des) ;?> | کلیک : <?php echo $row->click ;?> <hr>
<?php
endforeach;
}
خب تابع رو تعریف کردیم ، باز هم wpdb لعنتی که همه ازش میترسن رو global کردیم برای کار با کوئری ها .
جدولمون هم با پیشوندش صاف و صوف کردیم .
خطاهای کوئری رو هم گذاشتیم واسه دیباگ .
خب میریم واسه کوئری گرفتن کلاس wpdb که در اصل نسخه ابتدایی ezSql هست دارای یک متد get_result خوشکل هست که نتایج رو بصورت آبجکت برمیگردونه .
حالا ما با یک حلقه foreach اطلاعات رو نشون میدیم .
راستی شما sql خوندن بلدید؟
انتخاب همه از جدول لینکهای روزانه بر اساس شناسه قرار گیری در جدول از بزرگ به کوچک.
بعدم که نشون دادیم و ...
تعیین محتوای صفحه افزودن لینک
خب حالا باید دستورات اضافه کردن لینک ها رو بنویسیم
با یه نگاه به اون قسمت افزودن منو ها خط 66 میفهمید که تابع reza_dailylink_add_html وظیفه نمایش محتوا رو برعهده داره
اینا رو اضافه کنید (بنویسید خواهشاً تا یاد بگیرید)
کد:
#@86
/*reza_dailylink_add_html*/
function reza_dailylink_add_html()
{
global $wpdb;
$tbl = $wpdb->prefix . "reza_dailylink";
$wpdb->show_errors();
// start html
?>
<!-- افزودن لینک -->
<div class=warp>
<h3>افزودن لینک</h3>
<?php
// افزودن لینک به دیتابیس
if( ! empty($_POST['title']) and ! empty($_POST['addr']))
{
$title = htmlspecialchars(strip_tags(trim($_POST['title'])), ENT_QUOTES);
$addr = htmlspecialchars(strip_tags(trim($_POST['addr'])), ENT_QUOTES);
$des = htmlspecialchars(trim($_POST['des']), ENT_QUOTES);
$click = (int) $_POST['click'];
$do = $wpdb->query("INSERT INTO `$tbl` (title,addr,des,click) VALUES ('{$title}','{$addr}','{$des}',$click)");
if($do>0)
echo "<div id=message class='updated fade' ><p>لینک اضافه شد .</p></div>";
else
echo "<div id=message class='updated fade' style='background:pink' ><p>متاسفانه خطایی پیش آمد</p></div>";
}
?>
<form action='' method=post>
عنوان لینک : <input size=30 type=text name=title dir=rtl /> <br>
آدرس لینک : <input size=30 type=text name=addr dir=ltr /><br>
توضیحات : <textarea name=des rows=3 cols=40></textarea><br>
تعداد کلیک های پیشفرض : <input size=3 type=text name=click value=0 /><br>
<input type="submit" class="button" value="افزودن لینک" />
</form>
</div>
<?php
}
خب فکر کنم این قسمت یه کمی ...
طبق معمول اونچیزی که نیاز داریم wpdb لعنتی ، پس سه خط اول رو فهمیدید .
اون ایف میفارو هم ول کنید بیایید پایین سر فرمه خط 113
خب ما یک فرم داریم با 4 ورودی .
اسماشونم هست title , addr , des , click
فکر کنم میدونید هر کدوم واسه چین .
حالا دوباره برید بالا خط 100 سر ایف میفا 
اونجا چک کردیم اگه فرم رو ثبت کردم و title , addr خالی نبودن بیا یه کار انجام بده و اون کار چیه؟
آفرین اضافه کردن به دیتابیس
خب من توی 4 خط بعد از ایف ، اومدم 4 مقدار برای قرار گیری توی دیتابیس آماده کردم ، حتماً تا بحال اسم sql injection یا تزریق به دیتابس به گوشتون خورده .
اینجاست که باید تعیین کنید حتماً اون چیزی رو که میخواید وارد دیتابیس کنه .
مثلاً اگه به جای عنوان بزنید <script>alert("xss"); </script> ، تابع strip_tags اونو حذف میکنه ، یا مثلاً 100 تا اسکیپ بزنید تابع trim حذفش میکنه یا بهر دلیلی کاراکتری نامشخص درج شد ، تابع htmlspecialchars اونو به یک رشته امن تبدیل میکنه .
خلاصه اینا ریزه کاری هایی هست که باید همین اول راه بدونید .
خب اینارو فهمیدید دیگه ، حالا میرسیم به کوئریه !
نرو! بشین ، همش یه خطه !
کلاً میگن sql زبان آدمیزاده ، منتها دقیقاً کجای دنیا این زبونی حرف میزنن من نمیدونم ، مثلاً کوردی مینوشتن چی میشد؟
تی که با برریت
(te ka baa berret)
خب دستور رو فارسی میخونم براتون
وارد کن داخل جدول لینک های روزانه در فیلد های title,addr,des,click مقادیر $title,$addr,$des,$click رو.
بعدم چک میکنیم که وارد شده یا نه و پیغام مناسب رو نشون میدیم .
تعیین محتوای صفحه ویرایش لینک
حتماً میدونید که تابع این قسمتم باید reza_dailylink_edit_html باشه
دستورات زیر رو بنویسید در ادامه اش
کد:
#@123
/*reza_dailylink_edit_html*/
function reza_dailylink_edit_html()
{
echo 'این صفحه هنوز کامل نشده است .';
}
خب همونطور که از دستور معلمومه میگه این صفحه هنوز کامل نشده ، یعنی چی ؟
یعنی که من خسته ام دیگه باید بخوابم ، تا همینجاشم نوشتم خداوکیلی به کوب نوشتم فقط به خاطر گل روی دوستی بود که با وجود اینکه میدونست وبلاگ من حقیر سال به سال آپدیت نمیشه اما گفت ادامه آموزش چی میشه ؟ 
منم اینو توی انجمن گذاشتم ، برم بهش خبر بدم خوشحال بشه ماه رمضونی .
فکر کنم یکی اون ته گفت : آقا تموم شد ؟ ادامه نمیدید؟
خب باید بگم نه خیر ، هنوز کار داریم ، تازه گرم شدیم ، میخوایم این افزونه رو باهم بسازیم ، پس آروم آروم میریم جلو
کم کم امکانات ابزارک ، تابع برای قرار گیری در قالب و ... براش میذاریم .
خلاصه اینکه میخوام از وردپرس اتسعفا بدم ، باید یه چند نفرو راه بندازم 
افزونه رو هم تا اینجاش که تکمیل کردیم (که البته همشو من نوشتم و شما نیگا کردین) همینجا میذارم.
با تشکر رضا شیخله » rezaonline.net