I would like to combine 2 functions together, to consolidate code, and to be dynamic depending on how it is used. I do not know if this is possible.
First, lets lay out the basic use. In my example, I have Post and PostCategory models (and CRUD built). You create a category, then create a new post and assign it to the category. A post has the ability to be enabled
or disabled
. Essentially, you can create some new posts and have them not be viewable to the end users until your ready. One use-case would be a drip feed system, where you could add 100 posts and have one switch to enabled
every x days. That is beyond the scope of this.
views\post\_form.php
<div class="post-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'category_id')->dropDownList(
$model->getPostCategoryConst(),
['prompt'=> '- Category -']
)->label('Category')
?>
<?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'text')->textarea(['rows' => 6]) ?>
<?= $form->field($model, 'status')->dropDownList(
$model->getPostStatusConst(),
['prompt'=> '- Status -']
) ?>
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
Notice the drop down lists for category_id
and status
and the functions they call
\common\models\Post.php
const STATUS_ENABLED = 1;
const STATUS_DISABLED = 0;
public function getCategory()
{
return $this->hasOne(PostCategory::className(), ['id' => 'category_id']);
}
/* -- Added -- */
public function getPostCategoryConst()
{
return ArrayHelper::map(PostCategory::find()->orderBy('name DESC')->all(), 'id', 'name');
}
public function getPostStatusConst()
{
return [
self::STATUS_DISABLED => 'Disabled',
self::STATUS_ENABLED => 'Enabled',
];
}
Now this works just fine :) However, I don't like using get
as in getPostStatusConst()
as it isn't accessed like $model->postStatusConst
similar to how relations are with the "getter".
I would like to use these as "getters" as well though. In the index and view, it would be nice to also call the same functions. Instead of returning an array, to return a "nice name" such as "Enabled" or "Disabled"
For the sake of this, I won't rename the function, as I don't want to add any more confusion.
views\post\view.php
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'id',
'category.name',
'name',
'text:ntext',
'postStatusConst', // <-- Calls getPostStatusConst()
'created_at:datetime',
'updated_at:datetime',
],
]) ?>
Notice postStatusConst
is the same function as we used in _form
for our create action. In the _form, it needed to return an array for the drop down list. In our view, it just needs to return a nice name such as Enabled
or Disabled
.
I Tried
I tried this function in the Post model:
public function getPostStatusConst()
{
if ( isset($this) ) {
return ($this->status === self::STATUS_ENABLED) ? 'Enabled' : 'Disabled';
}
return [
self::STATUS_DISABLED => 'Disabled',
self::STATUS_ENABLED => 'Enabled',
];
}
That obviously didn't work :) I didn't expect it to, because I know $this
references itself in a class. It just shows what I am going for.
In relations, the hasOne()
seems to know whether we are using it as a direct call (Post::getCategory) or inline ($model->category->name)..
Question
Is it possible to have getPostStatusConst()
do the same? To use as $model->postStatusConst
to display Enabled
or Disabled
nicely, or as Post::getPostStatusConst()
to get the array for the drop down.