1
votes

I'm facing a very wierd situation concerning a quite simple task. I'm trying to create a very simple edit form in my application using cakephp 3.x version.

In my ContentsController::edit($contentID) method I'm loading the content entity to be edited like this

$content = $this->Contents->findById($contentID)->first()

and then I'm simply creating the respective view variable using set() method like that:

$this->set('content', $content);

In the view file - named edit.ctp - all I'm doing is to simply create a new form using FormHelper using the following piece of code:

<h2><?= __('Edit content: ') . $content->title; ?></h2>
<?php
echo $this->Form->create($content);
echo $this->Form->input('title', ['type' => 'text']);
echo $this->Form->input('alias', ['type' => 'text']);
echo $this->Form->input('body', ['type' => 'textarea']);
echo $this->Form->submit();
?>

The following code creates the form correctly but it does not load the default values in each input element from the $content entity. After doing some digging into the source code of the FormHelper I found out that when the FormHelper::create() method is called, it correctly loads the EntityContext interface using the $content entity. But for some reason, which I cannot explain, in each of the FormHelper::input() calls, internally the context interface is switching to NullContext so no data is loaded into the field.

Does anyone have an idea what am I doing wrong with that piece of code?

2
Change $this->Contents->findById($contentID)->first() for $this->Contents->get($contentID) here you have more info - Jacek B Budzynski
I thing both are same..post your edit method as well..is that all good ? - Manohar Khadka

2 Answers

1
votes

After some more digging I found the real cause of the issue. FormHelper works correctly and so does my query.

The issue has to do with the view file and how it is rendered. The whole picture is this.

My view (edit.ctp) was an extension of a common skeleton I created, namely edit_frm.ctp. So in my view file I was extending by calling $this->extend('/Common/edit_frm');

The structure of the edit_frm.ctp consists of three blocks, as shown below (I removed the html markup)

<?php
// Common/edit_frm.ctp
$this->fetch('formStart');
$this->fetch('formPrimaryOptions');
$this->fetch('formSecondaryOptions');
$this->fetch('formEnd');
?>

Now in my view file (edit.ctp) I was creating the blocks like that:

<?php
// Contents/edit.ctp
$this->extend('Common/edit_frm');

// The "formStart" block contains the opening of the form
$this->start('formStart');
echo $this->Form->create($content);
$this->end('formStart');

// The "formEnd" block contains the submit button and the form closing tag
$this->start('formEnd');
echo $this->Form->submit();
echo $this->Form->end();
$this->end('formEnd');

// "formPrimaryOptions" contains the main input fields
$this->start('formPrimaryOptions');
echo $this->Form->input('title', ['type' => 'text']);
echo $this->Form->input('alias', ['type' => 'text']);
echo $this->Form->input('body', ['type' => 'textarea']);
$this->end('formPrimaryOptions');
?>

As you see in my view file, I was building the formEnd block before the construction of the formPrimaryOptions block. Though in my skeleton the blocks are fetched in a different order.

Apparently in CakePHP when you extend a view combined with blocks of content in the actual view file you must create your blocks in the same order as they are fetched, otherwise you end up in weird situations like the one I was facing.

In any case, I had a very good lesson today!!

0
votes

Maybe you can do this instead of findById:

$content = $this->Contents->find('all')->where(['id' => $contentID])->first();