PDA

View Full Version : روش ساخت صفحه کانفیگ شخصی (حل شد)



shadecute
دوشنبه 22 اردیبهشت 1393, 12:04 عصر
سلام
فرض کنیم ما یه سیستم با ماژول های مختلف داریم

برای مثال در ویو ماژول یک 50 نوشته نمایش داده میشه
در ویو ماژول دو 20 نوشته نمایش داده میشه
و ....

برای این که این اعداد رو تغییر بدم هر دفعه باید برم و در کد این اعداد رو تغییر بدم
حالا من چظوری می تونم در یک فایل کانفیگ که به دیتابیستم وصل میشه این اعداد و ارقام رو در سیستم Set کنم
که این فایل کانفیگ به همه ماژول ها هم دسترسی داشته باشه هر تغییری در کانفیگ دادم در کل ماژول هام اعمال بشه

SlowCode
دوشنبه 22 اردیبهشت 1393, 17:34 عصر
سلام
میتونی تو فایل کانفیگ main.php این مقادیر رو به آرایه params اضافه کنی، مثلا:


'params'=>array(
// this is used in contact page
'adminEmail'=>'webmaster@example.com',
'newsViewLimit'=>50,
'productsViewLimit'=>20,
),

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


echo Yii::app()->params['newsViewLimit'];

shadecute
پنج شنبه 25 اردیبهشت 1393, 13:07 عصر
ممنون دوست من خیلی عالی بود تونستم درستش کنم فقط در مورد اینکه چظوری به دیتا بیس هم متصل بشه میشه راهنمایی کنید ؟ که این مقادیر رو در دیتا بیس ست کنیم .

MMSHFE
شنبه 27 اردیبهشت 1393, 11:58 صبح
یکی از کارهایی که توی برخی پروژه ها لازم میشه و کارفرما میخواد اینه که بتونه تنظیمات سایت رو (که معمولاً توی بخش params از فایل تنظیمات تعیین میکنید)، توی بخش مدیریت، ویرایش کنه. برای این کار من روش زیر رو توصیه میکنم:
توی فایل components/Controller.php که کلاس والد تمام کنترلرهای شماست، این متد رو اضافه کنید:

protected function beforeAction($action) {
// overwrite params with the DB version
$params = Yii::app()->params->toArray();
$keys = array_keys($params);
foreach($keys as $key) {
$setting = Settings::model()->find(array('condition'=>'`key`=:key','params'=>array(':key'=>$key)));
if($setting != null) {
$params[$key] = $setting->value;
}
}
Yii::app()->params = $params;
return parent::beforeAction($action);
}
حالا یک جدول به اسم settings توی دیتابیس با سه فیلد id و key و value بسازین که id کلید اصلی و key و value از نوع varchar با سایز 255 هست و key رو هم UNIQUE کنید. حالا برای تمام پارامترهایی که توی params معرفی کردین، یک رکورد توی این جدول ایجاد کنید که key میشه اندیس مربوطه در آرایه params (مثلاً adminEmail) و value هم مقدار پیشفرض اون هست (مثلاً webmaster@example.com). حالا تنها کاری که لازمه اینه که مدل مربوطه رو با Gii بسازین و اسمش رو هم Settings بگذارین.

اگه به کد فوق دقت کنید، میبینید که میاد مقادیر این جدول رو میخونه و توی آرایه params میچینه و Yii::app()->params رو هم با مقادیری که از دیتابیس خونده مقداردهی میکنه. از اونجا که این کار توی رویداد beforeAction انجام میشه، قبل از اینکه هر عملیاتی اتفاق بیفته، تنظیمات موجود در دیتابیس جایگزین تنظیمات موجود در فایل config/main.php میشه.

shadecute
شنبه 27 اردیبهشت 1393, 15:20 عصر
استاد تشکر
من این مراحل رو طی کردم
1- فایل params.php ساختم با مفادیری مشخص و تو فایل کانفیگم اینکلود کردم.

'params'=>require(dirname(__FILE__).'/params.php'),

2- داخل فایل params رو اینشکلی پر کردم

<?php
return array(

'adminEmail'=>'info@mysite.com',
'postsPerPage'=>10,

);



3- متدی که شما دادید رو در components/Controller.php کپی کردم
4- جداول رو ایجاد کردم و با Gii مد و ویو کنترل رو ایجاد کردم

من الان وارد ویرایش مقادیر میشم در http://localhost/site/settings/update/1 و مثلا ایمیل رو تغییر میدم در دیتا بیس تغییر میکنه اما در params تغییری ایجاد نمیشه
ببخشید خیلی تازه کارم و سوالات مبتدی می پرسم.

آیا رد داخل خود فایل params.php باید مقادیر Settings رو بخونم؟ میشه بیشتر راهنمایی کنید من تمام مراحل رو طبق آموزش رفتم اما تو خود params.php چیزی تغییر نمیکنه
ممنونم

MMSHFE
شنبه 27 اردیبهشت 1393, 15:24 عصر
نه دیگه نیازی نیست فایل رو تغییر بدین. الان توی صفحات سایتتون اگه Yii::app()->params['adminEmail'] رو بخونید، میبینید که اون چیزی که تو دیتابیس گذاشتین چاپ میشه نه اون چیزی که توی فایل تنظیمات هست. درواقع شما الان امکان تغییر پویای پارامترها رو دارین، بدون اینکه لازم باشه فایل تنظیمات اصلی رو دست بزنید. هروقت هم خواستین به تنظیمات اصلی برگردین کافیه رکورد مربوطه رو از جدول توی دیتابیس حذف کنید.

shadecute
شنبه 27 اردیبهشت 1393, 15:47 عصر
خیلیییییییییییییی ممنون استاد بله درسته .کار کرد . بقیه مقادیرم تست کردم همه چیز درسته . سپاس فراوان

shadecute
شنبه 27 اردیبهشت 1393, 16:25 عصر
فقط یه سوال . از Yii::app()->params['paramName']میشه تو خود فایل config.php هم استفاده کرد؟
نام اصلی سایت از کانفیگ اصلی

'name'=>'وبسایت من',


خونده میشه حالا من همین name رو تو params بردم و اینبر خوندمش Yii::app()->params['name'] اما Var_dump میگیرم در مقدار NULL بر میگرده البته فقط در کانفیگ ولی جایی دیگه echo میکنم مشکلی نداره
دلیلش چی می تونه باشه؟

MMSHFE
شنبه 27 اردیبهشت 1393, 16:30 عصر
نه تو خودش نمیشه چون هنوز شئ Application ساخته نشده. به index.php اصلی نگاه کنید. میبینید که فایل config رو میخونه و با کمک اون شئ رو میسازه. بنابراین توی خود فایل تنظیمات هنوز شئ وجود نداره که مقادیرش رو بخونیم. بجای این کار توی برنامه از Yii::app()->params['name'] بجای Yii::app()->name استفاده کنید (جاهایی که میخواستین اسم پروژه چاپ بشه).

shadecute
شنبه 24 خرداد 1393, 17:02 عصر
سلام یه سوال برام پیش اومده ما جدول رو درست کردیم key و value از نوع varchar با سایز 255 هست
خب تو گرید ویو همه فیلدامنو با textField لود میشه
حالا اگر ما یه گزینه های دیگه داشته باشیم مثلا فعال یا غیر فعال بودن سایت رو بخوایم در ستینگ کار کنیم و با checkbox مقدارشو بخوام بگیرم نمیشه
چون همه فیلد های key و value از نوع varchar هست و تو گرید ویو همه با textField لود میشه . این وسط چطوری می تونم مثل نمونه بالا از checkbox و یا textArea استفاده کنم؟

MMSHFE
شنبه 24 خرداد 1393, 17:06 عصر
یا باید با گرید ویو کار نکنید و خودتون دستی صفحه رو بسازین و برای بخشهایی که میخواین چک باکس باشه مقادیر رو از تو آرایه چک کنید و یا اینکه یک فیلد دیگه به جدول اضافه کنید (مثلاً isBoolean) که برای فیلدهای چک باکس مقدارش 1 میشه و توی گرید ویو بگین اگه این فیلد 1 بود، تکست نگذاره و چکباکس بسازه. در کل روش دستی رو ساده تر و بهتر میدونم تا اینکه بخواین درگیر بشین با گرید ویو. البته میتونید خودتون یک گرید ویوی سفارشی بسازین.

shadecute
شنبه 24 خرداد 1393, 17:14 عصر
ممنون
از روش دستی که فرمودید میشه یه مثال بزنید دستی منظورتون چطوریه.:متفکر:

MMSHFE
شنبه 24 خرداد 1393, 17:16 عصر
منظورم اینه که ویوی مربوط به تنظیمات رو خودتون بسازین. مثلاً من یک تگ سلکت میگذارم و میگم تنظیمات رو انتخاب کنه. وقتی انتخاب کرد، برحسب نوعش، چک باکس یا تکست باکس نشون میدم و تنظیمات رو هم بعدش ذخیره میکنم.

shimafaraz
جمعه 10 بهمن 1393, 06:35 صبح
سلام و عرض ادب. من بر روی وبلاگ Yii این کارهارو انجام دادم تا پارامترها رو در ستینگ تغییر بدم موفق شدم بعد از کلی کار انجامش بدم اما یه سوال
که این دوستمون پرسیده بودن.
===
:حالا اگر ما یه گزینه های دیگه داشته باشیم مثلا فعال یا غیر فعال بودن سایت رو بخوایم در ستینگ کار کنیم و با checkbox مقدارشو بخوام بگیرم نمیشه
چون همه فیلد های key و value از نوع varchar هست و تو گرید ویو همه با textField لود میشه . این وسط چطوری می تونم مثل نمونه بالا از checkbox و یا textArea استفاده کنم؟
===
من همچین موردی رو می خوام روش کار کنم اما نتونستم تازه کارم ممنون میشم یک سمپل بزارید دوستان

shimafaraz
جمعه 10 بهمن 1393, 06:37 صبح
:افسرده: ویو مربوط به تنظیمات رو چطوری ایجاد کنم که بتونه دیتا نشون بده و ذخیره کنه در دیتابیس؟:عصبانی++:

که هم تکست فیلد داشته باشه هم دراپ دان و چک باکس

MMSHFE
جمعه 10 بهمن 1393, 14:00 عصر
دستی بسازین. لازم نیست حتماً با Gii ساخته بشه. میتونید با CActiveForm کار کنید و از متدهای اون برای تولید چک باکس و... استفاده کنید.

shimafaraz
جمعه 10 بهمن 1393, 15:15 عصر
دستی بسازین. لازم نیست حتماً با Gii ساخته بشه. میتونید با CActiveForm کار کنید و از متدهای اون برای تولید چک باکس و... استفاده کنید.

مرسی :افسرده: ببخشید سوالاتم ابتداییه تازه 7 روزه با Yii دارم کار میکنم خیلی جاهاش برام گنگه شدیدا پوزش میخوام....
من در ویو settings یه فایل php به اسم test.php ایجاد کردم. که کدش اینجوریه


<div class="form">
<p class="alert alert-info">ویرایش تنظیمات</p>
<?php
$form = $this->beginWidget('CActiveForm', array (
'id' => 'setting-form',
'enableAjaxValidation' => false,
'htmlOptions' => array (
'class' => 'form-horizontal'
)
));
?>
<div class="form-group">
<label for="name" class="col-sm-3 control-label">نام کاربری </label>
<div class="col-sm-3">
<?php echo CHtml::textField('email',Yii::app()->params['email'],array('class'=>'form-control'))?>
</div>

</div>



<div class="form-group">
<label for="name" class="col-sm-3 control-label">فعال بودن</label>
<div class="col-sm-3">
<?php echo $form->checkBox($model,Yii::app()->params['active'], array('value'=>1, 'uncheckValue'=>0)); ?>))?>
</div>

</div>


<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<?php echo CHtml::submitButton( 'ویرایش',array('class'=>'btn btn-success','name'=>'btnSettingEdit')); ?>
</div>
</div>
<?php $this->endWidget(); ?>

</div>
<!-- form -->


تا اینجا درست انجام دادم؟ می خوام پارامتر email و active رو اینجا ادیت کنم .که اکتیو چک باکسه
اگر اشتباه نکنم باید تو مرحله ی بعد تو SettingsController باید اکشنش رو بنویسم؟ درسته؟ خب اکشنش رو نمی دونم چی باید بنویسم امکانش هست یه سمپل اکشن بدید که این فرمه کار کنه
( تو مدل که نیازی نیست کدی بنویسیم؟)
ممنون از زحمات شما

MMSHFE
جمعه 10 بهمن 1393, 22:54 عصر
نه باید خودتون یه CFormModel بسازین (مثل مدل LoginModel توی پروژه Skeleton اولیه که خود فریمورک براتون میسازه) و پارامترها رو داخلش تعریف کنید و بعد برای اون بیاین با CActiveForm فرم ویرایش درست کنید. تا فردا براتون یه نمونه اگه فرصت کردم میگذارم ولی فکر میکنم خودتون بتونین انجام بدین. ولیدیشن رولها رو هم باید بنویسید. مثلاً یه فیلد active داخلش تعریف کنید و براش رول boolean بگذارین و required نباشه. اینطوری میتونه کاربر توی فرم انتخابش نکنه. موقعی که فرم سابمیت میشه هم با validate چک میکنید خطایی نباشه و اگه نبود، اونوقت فیلدها رو توی Yii::app()->params قرار میدین یا توی دیتابیس ذخیره میکنید که در دفعات بعدی از اونجا خونده بشه.

MMSHFE
یک شنبه 12 بهمن 1393, 10:27 صبح
ببینید یه مثال ساده میزنم. فرض کنید توی دیتابیس توی جدول تنظیمات سه فیلد داریم: name و email و rtl که دوتای اولی متنی هستن و سومی چک باکس هست. خوب با این اوصاف، من میام برای جدول Settings یه فرم مدل میسازم:

class SettingsForm extends CFormModel
{
public $name;
public $email;
public $rtl;

public function rules()
{
return array(
array('name, email', 'required'),
array('name', 'length', 'max'=>255),
array('email', 'email'),
array('rtl', 'boolean'),
);
}

public function attributeLabels()
{
return array(
'name'=>'نام سایت',
'email'=>'پست الکترونیک',
'rtl'=>'راست به چپ',
);
}
}
خوب حالا با کمک Gii میایم توی قسمت Form Generator یه فرم میسازیم و کمی تغییرش میدیم تا این شکلی بشه:

<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'settings-form',
'enableAjaxValidation'=>true,
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'name'); ?>
<?php echo $form->textField($model,'name'); ?>
<?php echo $form->error($model,'name'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'email'); ?>
<?php echo $form->textField($model,'email'); ?>
<?php echo $form->error($model,'email'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'rtl'); ?>
<?php echo $form->checkBox($model,'rtl'); ?>
<?php echo $form->error($model,'rtl'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Submit'); ?>
</div>
<?php $this->endWidget(); ?>
</div>
به checkBox آخر دقت کنید. حالا باید کنترلر/اکشن مربوطه رو بسازیم. من اومدم یه SettingsController با اکشن index ساختم ولی شما میتونید با هر کنترلر/اکشن دلخواه کار کنید:

class SettingsController extends Controller
{
public function actionIndex()
{
$model = new SettingsForm;
if(isset($_POST['ajax']) && $_POST['ajax'] === 'settings-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
if(isset($_POST['SettingsForm'])) {
$model->attributes = $_POST['SettingsForm'];
if($model->validate()) {
}
// now save $model->attributes in DB
}
$this->render('index', array('model'=>$model));
}
}
اگه جایی مشکل بود بفرمایید تا بیشتر توضیح بدم.

shimafaraz
دوشنبه 13 بهمن 1393, 23:26 عصر
سلام ممنون از توجه شما
استاد من مراحل زیر رو انجام دادم
طبق فرمایش شما
1- در داخل پوشه ی models اومدم یه فایل php به نام SettingsForm ساختم و داخلش کد شما رو قرار دادم و فقط چون اسم فیلدام چیز دیگری بود به صورت زیر وارد کردم

<?php
class SettingsForm extends CFormModel
{
public $name;
public $adminEmail;
public $active;

public function rules()
{
return array(
array('name,adminEmail','required'),
array('name','length', 'max'=>255),
array('adminEmail', 'adminEmail'),
array('active', 'boolean'),
);
}

public function attributeLabels()
{
return array(
'name'=>'نام سایت',
'adminEmail'=>'پست الکترونیک',
'active'=>'فعال کردن',
);
}
}
فقط اون خطی که قرمز کردم نمیزاره فرمم کار کنه وقتی خذفش میکنم فرم لود میشه در صورتی که باشه پیغام زیر رو میده
include(adminEmail.php): failed to open stream: No such file or directory



بعدش اومدم در مسیر Views در settings یک فایل به اسم test.php درست کردم
و داخلش رو همین کدرو گذاشتم


<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'settings-form',
'enableAjaxValidation'=>true,
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'name'); ?>
<?php echo $form->textField($model,'name'); ?>
<?php echo $form->error($model,'name'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'adminEmail'); ?>
<?php echo $form->textField($model,'adminEmail'); ?>
<?php echo $form->error($model,'adminEmail'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'active'); ?>
<?php echo $form->checkBox($model,'active'); ?>
<?php echo $form->error($model,'active'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Submit'); ?>
</div>
<?php $this->endWidget(); ?>
</div>
بعدش در خود SettingsController اکشن رو قرار دادم به اسم test اینجوری

public function actionTest()
{
$model = new SettingsForm;
if(isset($_POST['ajax']) && $_POST['ajax'] === 'settings-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
if(isset($_POST['SettingsForm'])) {
$model->attributes = $_POST['SettingsForm'];
if($model->validate()) {
}
// now save $model->attributes in DB
}
$this->render('test', array('model'=>$model));
}
با تمام این مراحل که شما فرمودید فرمم لود میشه ولی داخل فیلد ها خالیه و وقتی چیزی داخلش می نویسمو Save می کنم چیزی در دیتابیس ذخیره نمیشه
کجای کارم اشکال داره؟ اسم table تودیتابیس هم settings هست که بر اساس آموزش اولیه تاپیک خودتون آموزش داده بودید پیش رفتم

MMSHFE
دوشنبه 13 بهمن 1393, 23:35 عصر
خوب شما الان یه فرم مدل دارین نه یه اکتیورکورد. باید اونجایی که کامنت گذاشتم گفتم تو دیتابیس ذخیره کنید، یه شئ از مدل Settings بسازین یا همونی که هست رو بخونین و فیلدهاش رو با فیلدهای متناظر از مدل فرم مقداردهی کنید و بعد با صدا زدن متد save روی اکتیورکورد، اون رو توی دیتابیس ذخیره کنید.

shimafaraz
دوشنبه 13 بهمن 1393, 23:39 عصر
:افسرده:
public function actionTest()
{
$model = new SettingsForm;
if(isset($_POST['ajax']) && $_POST['ajax'] === 'settings-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
if(isset($_POST['SettingsForm'])) {
$model->attributes = $_POST['SettingsForm'];
if($model->validate()) {
}
$model=new Settings;

if (isset($_POST['Settings'])) {
$model->attributes=$_POST['Settings'];
if ($model->save()) {
}
} }
$this->render('test', array('model'=>$model));
}
:افسرده:
اشتباه نوشتم :( کار نمیکنه گیج شدم:گریه:

MMSHFE
سه شنبه 14 بهمن 1393, 09:39 صبح
باید فیلدهاتون توی دیتابیس همنام با فیلدهای مدل فرم باشه وگرنه باید جداگانه ذخیره کنید. برای مثال:

public function actionTest()
{
$model = new SettingsForm;
if(isset($_POST['ajax']) && $_POST['ajax'] === 'settings-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
if(isset($_POST['SettingsForm'])) {
$model->attributes = $_POST['SettingsForm'];
if($model->validate()) {
$settings = new Settings;
if(isset($_POST['Settings'])) {
$settings->attributes = $model->attributes;
/* OR assign fields individually if field names are different
* e.g. :
* $settings->appname = $model->name;
* $settings->adminmail = $model->adminEemail;
* $settings->is_active = $model->active;
*/
if ($settings->save()) {
}
}
}
}
$this->render('test', array('model'=>$model));
}
برای اعتبارسنجی ایمیل هم باید اینطوری بنویسید:

public function rules()
{
return array(
array('name,adminEmail','required'),
array('name','length', 'max'=>255),
array('adminEmail', 'email'),
array('active', 'boolean'),
);
}
دقت کنید که اسم ولیدیتور ایمیل، email هست و اسم فیلد شما adminEmail

shimafaraz
چهارشنبه 15 بهمن 1393, 00:58 صبح
استاد ممنون من همین کد رو استفاده کردم
public function actionTest()
{
$model = new SettingsForm;
if(isset($_POST['ajax']) && $_POST['ajax'] === 'settings-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
if(isset($_POST['SettingsForm'])) {
$model->attributes = $_POST['SettingsForm'];
if($model->validate()) {
$settings = new Settings;
if(isset($_POST['Settings'])) {
$settings->attributes = $model->attributes;

$settings->name = $model->name;
$settings->adminEemail = $model->adminEmail;
$settings->active = $model->active;

if ($settings->save()) {
}
}
}
}
$this->render('test', array('model'=>$model));
}
اما نشد
ذخیره نشد
اسامی فیلد ها ر و هم درست وارد کردم اینم عکس دیتابیس من

128173

MMSHFE
چهارشنبه 15 بهمن 1393, 11:17 صبح
خوب شما الان رکورد دارین نه فیلد. باید اینطوری کار کنید:

public function actionTest()
{
$model = new SettingsForm;
if(isset($_POST['ajax']) && $_POST['ajax'] === 'settings-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
if(isset($_POST['SettingsForm'])) {
$model->attributes = $_POST['SettingsForm'];
if($model->validate()) {
$settings = new Settings;
if(isset($_POST['Settings'])) {
foreach($_POST['Settings'] as $key => $value) {
if($setting = Settings::model()->find('LOWER(`key`)=:key',array(':key'=>strtolower($key)))) {
$setting->value = $value;
$setting->save();
}
}
}
}
}
$this->render('test', array('model'=>$model));
}
اگه میخواین موقع نمایش فرم هم مقادیر قبلی توش نوشته شده باشه باید بعد از ساخت شئ مدل فرم (settings) فیلدهاش رو با مقدار value رکورد متناظر از جدول settings توی دیتابیس پر کنید.

shadecute
سه شنبه 04 فروردین 1394, 03:51 صبح
درود بر استاد شهرکی و دوستان برنامه نویس سال نو مبارک
-
دوستان این صفحه رو ببینید (http://www.yiiframework.com/wiki/304/setting-application-parameters-dynamically-in-the-back-end/)

یک روش ساخت کانفیگ هست . من واسه تمرین یکمی اجراش کردم و بدون مشکلم کار میکنم ولی به جای دیتابیس مقادیر رو رمز نگاری میکنه و در یک فایل params.inc ذخیره و از همین فایل می خونه تنظیمات رو .
آیا استفاده از این روش رو پیشنهاد میکنید؟
مورد تاییده؟
اینکه در params.inc تنظیمات رمز نگاری میشه و ذخیره میشه ایرادی فنی و امنیتی نداره؟ ممنون میشم راهنمایی کنید