پلاگین رایگان وردپرس

در شرح پلاگین مدیریت ثبت شرکت،طراحی جداول

بسم الله الرحمن الرحیم

سلام علیکم

طبق روال قبلی این بار هم شرح و نکات پلاگینی که اخیرا تمام کردم رو اراده میدم خدمت دوستان.

قیمت تمام شده این پلاگین رو در انتهای سری مطلب می گم.

توی این قسمت بخش طراحی جداول رو توضیح میدم

پلاگین مدیریت ثبت شرکت

این پلاگین باید این کارها رو انجام می داد:

  1. افزودن و ویراش شرکتها از مدیریت
  2. پیوست کردن مدارکی به هر شرکت(مدارک یا مراحلی مثل ثبت شرکت،تغییر در اساس نامه و…،اسمش رو مدارک یا Cert گذاشتم به دلایلی)
  3. نمایش به کاربر شرکت توسط رمزی که در مدیریت براش تعیین شده

 

ظاهر کار ساده ست نه؟

بطن کار چی؟حالا خواهیم دید.

اسم پلاگین رو می ذاریم company reg manager و ادامه می دیم مطلب رو.

طراحی جدول پلاگین مدیریت ثبت شرکت

خب فرض می کنیم شرکت A توسط مدیریت ثبت باید بشه،پس یه جدول میخوایم برای ثبت شرکتها،اسمش رو می ذاریم،co_regs

خب حالا این شرکت می تونه مدارک X,Yو…. رو داشته باشه،نکته ای هست،اون هم این که سفارش دهنده فرمودن که مدارم فقط دو عنوان هستند و تمام،پس می تونستم از جدول استفاده نکنم و آنا با یه آرایه یا فایل XML و امثالهم کار رو تموم کنم،اما تجربه بهم می گفت که از جدول استفاده کن،و آینده رو مدنظر داشته باش،شاید فردا نیاز باشه مدارک دیگه ای هم اضاف بشه(که اینطور هم شد)،خب اسم این جدول رو می ذارم،co_cert

حالا هر Cert مراحلی داره،که بهش میگیم Step ،حالا میتونیم برای این استپ ها هم جدول طراجی کنیم،اما بهتر نیست Cert رو با Step توی یه جدول بذاریم؟چرا که تعداد Certها خیلی کم هستند،پس از همون جدول co_cert استفاده می کنیم،و اسمش رو می کنیم:co_cert_step

از اون جایی که رابطه بین اینها چند به چند هست باید جدول میانه رو هم مد نظر بگیریم،اسم جدول میانه رو می ذاریم:co_regs_cert_step ، که ترکیبی از اسم دو جدول هستش.

پس کار نهایی ما شد این:

[code]
$co_regs =$wpdb->prefix.'co_regs';
$sql[] = "CREATE TABLE IF NOT EXISTS `$co_regs` (
`id` int(20) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL,
`code` varchar(200) NOT NULL,
`pass` varchar(200) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;";

$co_cert_step =$wpdb->prefix.'co_cert_step';
$sql[] = "CREATE TABLE IF NOT EXISTS `$co_cert_step` (
`id` int(20) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL,
`desc` varchar(200) NOT NULL,
`parent` int(20) NULL,
`type` ENUM( 'cert' , 'step'),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;";

$co_regs_cert_step =$wpdb->prefix.'co_regs_cert_step';
$sql[] = "CREATE TABLE IF NOT EXISTS `$co_regs_cert_step` (
`co_id` int(20) NOT NULL,
`cert_or_step_id` int(20) NOT NULL,
`update_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`co_id` , `cert_or_step_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;";

[/code]

 

 

 

در شرح پلاگین tiny mass mailer – قسمت دوم

بسم الله الرحمن الرحیم

سلام

نکته هایی از قسمت اول شرح پلاگین میلر ریز مونده بود که اینجا عرض می کنم خدمت دوستان.

خب باید دوتا آپشن به این سیستم اضافه میشد:

  • یکی اینکه آمار ایمیلهایی که باز میشه رو ثبت کنه(تعداد باز شدن ایمیل)
  • و دومی اینکه لینکهایی که باز میشه رو هم آمار بگیره(تعداد کلیک)

ثبت آمار باز کردن ایمیلها

راه حلی که برای مورد اول به ذهنم رسید استفاده از یک عکس با src خاصی بود که یک کدPHP در انتظارش بود که به محض باز شدن با پارامترهایی که بهش پاس داده میشد آمار رو ثبت و نهایتا عکس کذایی رو نشون می داد،لازم به ذکره عکس مورد نظر یک پیکسل در یک پیکسل در نظر گرفته شد تا به چشم نیاد.

خب،اول باید موقع ثبت ارسال جدید این عکس رو خودکار اضافه می کردم به انتهای متن،عکس این هست:

[code]

$txt = $txt . '<hr/><img src="'.get_bloginfo('siteurl').'/?tinymassmailer_t='.$send_id.'">';

[/code]

 

پارامتر $send_id برای ثبت آمار موقع باز شدن عکس استفاده میشه،طبیعیه که پارامترهای دیگه ای هم میشد اضاف کرد.

و این هم کد منتظر عکس بالا:

[code]

$_tinymassmailer_make_tracking_transient = '_tinymassmailer_make_tracking_run_check_'.$_SERVER['REMOTE_ADDR'];

if(isset($_GET['tinymassmailer_t'])){
$sImage = _tinymassmailer_PATH.'css/img/live.jpg';
if(get_transient( $_tinymassmailer_make_tracking_transient )) { header("Content-Type: image/jpeg"); echo file_get_contents($sImage);die(); };
set_transient( $_tinymassmailer_make_tracking_transient, 'locked_for_10_seconds', 10 );

//update opens emails
global $wpdb;
$send_id =(int)($_GET['tinymassmailer_t']);
$tiniymassm_sends =$wpdb->prefix.'tiniymassm_sends';
$row = $wpdb->get_row("select * from $tiniymassm_sends where id=$send_id");
if(!$row) return;

$new_opens = (int)$row->opens;
$new_opens += 1;
$wpdb->update($tiniymassm_sends,
array('opens' => $new_opens),
array('id' => $send_id),
array('%d'),
array('%d')
);

header("Content-Type: image/jpeg");
echo file_get_contents($sImage);
die();
}

[/code]

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

توجه:توی قسمت قبل از یه فایل برای حد تداخل اجرای هم زمان استفاده کرده بودیم،به دلایلی ترجیح دادم از set_transient استفاده کنم،که ان شاءالله بعد در موردش بحث خواهیم کرد.

 

ثبت کلیکها به هنگام کلیک بر روی لینک در ایمیل

باید آمار کلیک ها رو هم در می آوردم،برای این کار به هنگام ثبت ارسال تمام لینکها رو آنا عوض کردم تا وقت کلیک به آدرس مشخض شده برن و بعد از ثبت آمار به لینک اصلی هدایت بشن.

به دلایلی برای این ویرایش از Regex استفاده نکردم،چون درست و درمون فارسی رو ساپورت نمیکنه،پس تنها راهی که به ذهنم رسید استفاده از simple_html_dom عزیز بود:

[code]

$html = str_get_html($txt);
$url = get_bloginfo('siteurl').'/?tinymassmailer_c='.$send_id.'&tmm_url=';
foreach($html->find('a') as $key => $v){
$html->find('a' , $key)->href =  $url.str_replace('"' , '' ,$html->find('a' , $key)->href);
}

$txt = $html;

[/code]

اما کد PHP منتظر این لینک:

[code]

if(isset($_GET['tinymassmailer_c'])){
$url = trim($_GET['tmm_url']);
if(get_transient( $_tinymassmailer_make_tracking_transient )) { header('location:'.$url); die(); };
global $wpdb;
$send_id =(int)($_GET['tinymassmailer_c']);
$tiniymassm_sends =$wpdb->prefix.'tiniymassm_sends';
$row = $wpdb->get_row("select * from $tiniymassm_sends where id=$send_id");
if(!$row) return;

$new_clicks = (int)$row->clicks;
$new_clicks += 1;
$wpdb->update($tiniymassm_sends,
array('clicks' => $new_clicks),
array('id' => $send_id),
array('%d'),
array('%d')
);

//add url hits to DB

$tiniymassm_urls =$wpdb->prefix.'tiniymassm_urls';
$url_res = $wpdb->get_row($wpdb->prepare("SELECT * FROM $tiniymassm_urls where `url` = '%s'" , array($url)));
if($url_res){
$wpdb->update(
$tiniymassm_urls,
array(
'hits' => $url_res->hits+1
),
array('id' => $url_res->id),
array('%d'),
array('%d')
);
}else{
$wpdb->insert(
$tiniymassm_urls,
array(
'url'         => $url,
'hits'        =>    ۱ ,
),
array('%s' , '%d' , '%d')
);
}

header('location:'.$url);
die();

}

[/code]

دریافت آخرین کاربر بعدی در MYSQL

یه نکته ی دیگه ی این پلاگین این بود که نیاز بود برای هر ارسال آی دی یوزر بعد رو واکشی و به ایمیلش ارسال داشته باشم،اما مشکل این هست که خیلی از بانکهای اطلاعاتی مثل روز اولشون به ترتیب شماره گذاری شده نمی مونند،به هرحال شاید یوزری حذف بشه و یا ویرایش و این ترتیب به هم بریزه،پس راه حل چی بود؟

ببینید:

[code]

$wpdb->get_row("SELECT * FROM $wpdb->users WHERE ID > $last_id ORDER BY ID LIMIT 1;");

[/code]

این میگه اولین آی دی ای رو برام برگردون که از آخرین آی دی من بزرگتر باشه 🙂

نکات دیگه ای هم هست که از گفتنش صرف نظر می کنم.

اگر از این مطالب استفاده بردین،صلواتی برای یاد شهدا و تسریع ظهور بفرستید.

در شرح پلاگین tiny mass mailer

بسم الله الرحمن الرحیم

سلام

ماه رمضان کریم تهنیت و شهادت اول مظلوم عالم تسلیت باد.

از این پس شرح برخی پروژه های وردپرس رو اینجا خواهم گفت تا شاید برای خودم و احیانا کس دیگه ای مفید واقع بشه و به کارش بیاد.

 

این بار میریم سراغ:

پلاگین TinyMass Mailer یا میلر ریز

هدفی که توی این پلاگین باید مد نظر گرفته می شد میتونه شامل موارد زیر باشه:

  • اول اینکه پلاگین باید تا حد امکان ساده طراحی بشه تا کاربر رو گیج نکنه
  • هدف اصلی که باعث ساخت این پلاگین شد نیاز به ارسال ایمیل به کلیه یوزرهای سایت بود
  • استفاده از SMTPهای مختلف در آن واحد جهت

خب همه می دونیم که نمونه های مشابه توی بازار موجوده حتی بصورت رایگان و کاملتر،تا حدی که برخی خودشون رو جایگیزین مستقلی برای سرویس Mailchimp می دونن.

اما آیا واقعا همه این امکانات و شلوغی ها برای یک ارسال گروهی به تمام یوزرها نیاز بوده؟حال اینکه این پلاگین فقط و فقط کارش همین یک مورد هست،یعنی ارسال یک ایمیل بدون اسپم به تمامی یوزرهای موجود سایت.

 

یکی از ویژگی هایی که این پلاگین داره این هست که قابلیت این رو داره که چندین اکانت SMTP بگیره و محدودیت ارسالشو در ساعت رو هم بگیره و بعد شروع به ارسال کنه،بدین صورت امکان اسپم شدن ایمیلها کم و بلاک شدن اکانتها ازبین میره.

 

جزئیات فنی پلاگین TinyMass Mailer یا میلر ریز

رسیدیم به جزئیات فنی و پیاده سازی.

۱ اولین کاری که انجام دادم اسم پلاگین رو به “سیستم سازنده پلاگینی” که طراحی کردم دادم تا ساختار اولیه منوها،ادمین،Ajax،کد کوتاه و… همه و همه اتو ساخته بشن،این کار باعث صرفه جویی زیادی میشه،چرا که اکثر کارهای تکراری موجود در ساخت پلاگین حذف میشه.

 

۲ اضافاتی که نیاز نبود رو از خروجی سیستم بالا حذف کردم و جاهایی رو کلا بخاطر پلاگین بازنوسی کردم(همیشه یک نوع کد کار رو راه نمیندازه)

 

۳ جدولی برای ارسالها در نظر گرفتم،به این صورت:

[code]
"CREATE TABLE IF NOT EXISTS `$tiniymassm_sends` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`last_user_id` varchar(200) NOT NULL,
`last_sent_time` varchar(200) NOT NULL,
`start_date` varchar(200) NOT NULL,
`end_date` varchar(200) NULL,
`smtp` varchar(200) NULL,
`text` text NOT NULL,
`subject` varchar(200) NOT NULL,
`state` ENUM( 'completed' , 'new' ,'canceled' ),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;"
[/code]

این جدول وظیفه داره ارسالها رو نگه داره،چیزهایی مثل آخرین زمان ارسال،آخرین کاربری که ارسال براش انجام شده،شروع و پایان ارسال،موضوع و متن و حالت ارسال که جدید هست یا تمام و یا کنسل شده ؟

۴ برای ارسال ایمیل تصمیم گرفتم از کلاس معروف PHPMailer استفاده کنم.

… چون تعداد SMTPها باید توسط کاربر وارد میشد پس گزینه ای گذاشتم برای وارد کردن تعداد توسط کاربر و بعد از اون به مقدار SMTPها تنظیمات مورد نظر رو ایجاد کردم.

هر SMTP با دکمه ای که کنارش گذاشتم قابلیت بررسی صحت تنظیمات رو داشت که برای این مورد از کد زیر استفاده کردم:

[code]
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->SMTPDebug = 0; // debugging: 1 = errors and messages, 2 = messages only
$mail->SMTPAuth = true; // authentication enabled
$mail->SMTPSecure = $secure; // secure transfer enabled REQUIRED for GMail
$mail->Host = $host;
$mail->Port = $port;
$mail->Username = $user;
$mail->Password = $pass;
$mail->SetFrom($user, $user);
$mail->Subject = 'SMTP Test From tinymassmailer';
$mail->Body = 'SMTP Test From tinymassmailer';
$mail->AddAddress($user);
if(!$mail->smtpConnect()) {
// return $mail->ErrorInfo;
return 'Error!';
} else {
return 'OK!';
}
[/code]

خب حالا پلاگین باید در هر اجرای وردپرس از جدولی که ساخته شده بود اولین ارسال جدید رو واکشی کنه

[code]
$tiniymassm_sends =$wpdb->prefix.'tiniymassm_sends';
$result = $wpdb->get_results("SELECT * from $tiniymassm_sends where `state`='new' limit 1");
//if no emails for send
if(count($result) == 0) return;
//
[/code]

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

[code]
//if one hour not ended
if( (time() - $result[0]->last_sent_time) < 3600) return;
//
[/code]

برای تداخل اجرای همزمان به هنگام اجرا فایلی با نام .in_process ساخته میشه که پس از اجرا حذف میشه و درصورت وجود این فایل عملیات ارسال انجام نمیشه چرا که پرسه ی دیگه ای در حال انجام هست.

[code]
//if sending is in process
if(file_exists(_tinymassmailer_DIR.'.in_process')) return;
//
[/code]

در نهایت باید پس از اتمام کار به مدیریت اطلاع رسانی بشه و وضعیت کار به Completed تغییر پیدا کنه.

 

کوئری از سفارشات ووکامرس

بسم الله

سلام

نمونه زیر کوئری از سفارشات ووکامرس میگیره،اگر توی wp_query مقدار post_type رو shop_order بذارید ، قانونا باید برگردونه ، اما این اتفاق نمیفته،چون مقدار post_status این CPT مثل پستها نیست،کد زیر این کار رو انجام میده:

[code]
$wc= new WP_Query(array(
'post_type' => 'shop_order',
'post_status' =>'wc-completed' // wc-completed , wc-cancelled
));
if($wc->have_posts()){
while($wc->have_posts()) {
$wc->the_post();
the_title();
}
}
wp_reset_query();
[/code]

 

ارور جالب وردپرس،خطا روی خود جی کوئری

بسم الله الرحمن الرحیم.

با یه خطای جالب بر خوردم امروز،سایت کلی ارور JavaScript داشت،که یکی از ارورهاش دقیقا خود جی کوئری بود.

مضمون خطا این بود:

[code lang="js"]
Error: Syntax error, unrecognized expression: http://#

throw new Error("Syntax error, unrecognized expression: " + a)

[/code]

و همچنین خطاهای بعدش:

[code lang="js"]
TypeError: jQuery(...).superslides is not a function

jQuery('.max-hero').superslides({

TypeError: jQuery(...).doubleTapToGo is not a function

jQuery( '#nav li:has(ul)' ).doubleTapToGo();

TypeError: jQuery(...).flexslider is not a function

jQuery('.flexslider').flexslider();

[/code]

طبق تجربه ظاهرا یا جی کوئری یا کتابخونه های مربوطه که توی کد هست درست لود نشدند.

این خط توجه مو به خودش جلب کرد:  http://#

سورس سایت رو آوردم و دنبال همین تیکه گشتم،و پیدا کردم! این مربوط به  مقدار href توی یه المنت a بود،مقدار روی توی وردپرس و از مدیریت یه مقدار صحیح دادم و تمام اون خطاهای بالا رفع شد!

اما علت این خط چی بود؟آیا درسته به خاطر یه سهل انگاری کوچک کل سایت به دردسر بیفته؟