Hi everyone,
I need some help with saving many to many relations associated data using forms for Cakephp 3.x.
I have the tables publications
, artifacts
and they have a many to many relation using table artifacts_publications
. This association table has additional fields exact_reference
, publication_comments
and publication_type
.
I’m trying to link artifacts to a publication when editing the selected publication using the publication form.
The resulting post data from the form is shown below:
[ 'ids' => [ (int) 0 => '1', (int) 1 => '5' ], 'bibtexkey' => 'Abusch1981', 'year' => '1970', 'entry_type_id' => '5', 'address' => '', 'annote' => '', 'book_title' => 'In Honor of Ernest R. Lacheman on His Seventy-fifth Birthday, April 29, 1981', 'chapter' => '', 'crossref' => '', 'edition' => '', 'how_published' => 'test', 'institution' => 'ashdfkahsg', 'journal_id' => '49', 'month' => '', 'note' => '', 'number' => '', 'organization' => '', 'pages' => '1-9', 'publisher' => 'Eisenbrauns: Winona Lake', 'school' => '', 'title' => 'Notes on a Pair of Matching Texts: A Shepherd’s Bulla and an Owner’s Receipt', 'volume' => '1', 'publication_history' => '', 'series' => 'SCCNH', 'oclc' => '', 'designation' => 'designation new', 'artifacts' => [ (int) 0 => [ 'id' => '3', '_joinData' => [ 'exact_reference' => 'Ref 1', 'publication_type' => 'primary', 'publication_comments' => '42x53x19; Vocabulary 9; Qa XVI,2, unter der Abgleichung der Schicht III, 1,5 m über der Höhe des Kalksteinsockels (t.a.q. IIIc); veröffentlicht in: ATU 1, 539; bereits kommentiert von A. Falkenstein, UVB 3, 12 und ATU 1, S. 43-45.' ] ], (int) 1 => [ 'id' => '4', '_joinData' => [ 'exact_reference' => 'Ref 2', 'publication_type' => 'primary', 'publication_comments' => '26x23x23; Lú A 9-10.?.?; Fundstelle wie W 9123,d; veröffentlicht in: ATU 1, 489.' ] ] ] ]
But on using patchEntity() to load the data into the entity object, the resulting value for the ‘artifacts’ field is null (‘artifacts’ => null). Can someone help me with correcting what I am doing wrong?
Code:
PublicationsController.php (part of the code):
/**
* Merging selected publications.
*/
public function merge($id = null) {
if ($this->request->is('post')) {
$data = $this->request->getData();
debug($data);
if ((!isset($data['ids'])) or count($data['ids']) < 2) {
$this->Flash->error(__('Atleast two publications need to be selected for merging.'));
return $this->redirect(['action' => 'mergeSelect']);
}
$publication_merge = $this->Publications->get(1, [
'contain' => ['Artifacts']
]);
$publications = $this->Publications->find('all', [
'conditions' => ['id IN' => $data['ids']],
'contain' => ['Authors', 'Artifacts']
]);
if (isset($id)) {
$publication_merge = $this->Publications->patchEntity($publication_merge, $data, [
'associated' => ['Artifacts']
]);
debug($publication_merge);
if($this->Publications->save($publication_merge)) {
foreach (array_slice($publications->toArray(),1) as $entity) {
$this->Publications->delete($entity);
}
$this->Flash->success('Successfully merged all publications.');
} else {
$this->Flash->error('Could not merge.');
}
}
// debug($publication);
}
$entryTypes = $this->Publications->EntryTypes->find('list', [
'keyField' => 'id',
'valueField' => 'label',
'order' => 'label'
])->toArray();
$journals = $this->Publications->Journals->find('list', [
'keyField' => 'id',
'valueField' => 'journal',
'order' => 'journal'
])->toArray();
$publication_type_options = [
'primary' => 'primary',
'electronic' => 'electronic',
'citation' => 'citation',
'collation' => 'collation',
'history' => 'history',
'other' => 'other'
];
$this->set(compact('publications', 'publication_merge', 'entryTypes', 'journals', 'publication_type_options'));
}
merge.ctp:
<h3 class="display-4 pt-3"><?= __('Selected Publications') ?></h3>
<?= $this->Form->create($publication_merge, ['action' => 'merge', 'type' => 'post']) ?>
<table cellpadding="0" cellspacing="0" class="table-bootstrap my-3">
<thead>
<tr>
<!-- <th scope="col"><?= $this->Paginator->sort('id') ?></th> -->
<th scope="col"><?= $this->Paginator->sort('year') ?></th>
<th scope="col"><?= $this->Paginator->sort('entry_type_id') ?></th>
<th scope="col"><?= $this->Paginator->sort('address') ?></th>
<th scope="col"><?= $this->Paginator->sort('annote') ?></th>
<th scope="col"><?= $this->Paginator->sort('book_title') ?></th>
<th scope="col"><?= $this->Paginator->sort('chapter') ?></th>
<th scope="col"><?= $this->Paginator->sort('crossref') ?></th>
<th scope="col"><?= $this->Paginator->sort('edition') ?></th>
<th scope="col"><?= $this->Paginator->sort('how_published') ?></th>
<th scope="col"><?= $this->Paginator->sort('institution') ?></th>
<th scope="col"><?= $this->Paginator->sort('journal_id') ?></th>
<th scope="col"><?= $this->Paginator->sort('month') ?></th>
<th scope="col"><?= $this->Paginator->sort('note') ?></th>
<th scope="col"><?= $this->Paginator->sort('number') ?></th>
<th scope="col"><?= $this->Paginator->sort('organization') ?></th>
<th scope="col"><?= $this->Paginator->sort('pages') ?></th>
<th scope="col"><?= $this->Paginator->sort('publisher') ?></th>
<th scope="col"><?= $this->Paginator->sort('school') ?></th>
<th scope="col"><?= $this->Paginator->sort('title') ?></th>
<th scope="col"><?= $this->Paginator->sort('volume') ?></th>
<th scope="col"><?= $this->Paginator->sort('abbreviation_id') ?></th>
<th scope="col"><?= $this->Paginator->sort('series') ?></th>
<th scope="col"><?= $this->Paginator->sort('oclc') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($publications as $publication): ?>
<tr>
<!-- <td><?= $this->Number->format($publication->id) ?></td> -->
<?= $this->Form->input('ids[]', ['type' => 'hidden', 'value' => $publication->id]) ?>
<td><?= h($publication->year) ?></td>
<td><?= $publication->has('entry_type') ? $this->Html->link($publication->entry_type->title, ['controller' => 'EntryTypes', 'action' => 'view', $publication->entry_type->id]) : '' ?></td>
<td><?= h($publication->address) ?></td>
<td><?= h($publication->annote) ?></td>
<td><?= h($publication->book_title) ?></td>
<td><?= h($publication->chapter) ?></td>
<td><?= h($publication->crossref) ?></td>
<td><?= h($publication->edition) ?></td>
<td><?= h($publication->how_published) ?></td>
<td><?= h($publication->institution) ?></td>
<td><?= $publication->has('journal') ? $this->Html->link($publication->journal->journal, ['controller' => 'Journals', 'action' => 'view', $publication->journal->id]) : '' ?></td>
<td><?= h($publication->month) ?></td>
<td><?= h($publication->note) ?></td>
<td><?= h($publication->number) ?></td>
<td><?= h($publication->organization) ?></td>
<td><?= h($publication->pages) ?></td>
<td><?= h($publication->publisher) ?></td>
<td><?= h($publication->school) ?></td>
<td><?= h($publication->title) ?></td>
<td><?= h($publication->volume) ?></td>
<td><?= $publication->has('abbreviation') ? $this->Html->link($publication->abbreviation->abbreviation, ['controller' => 'Abbreviations', 'action' => 'view', $publication->abbreviation->id]) : '' ?></td>
<td><?= h($publication->series) ?></td>
<td><?= $this->Number->format($publication->oclc) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<h3 class="display-4 pt-3"><?= __('Merged Publication Details') ?></h3>
<div class="col-lg boxed">
<legend class="capital-heading"><?= __('Publication Data') ?></legend>
<table cellpadding="10" cellspacing="10">
<tr>
<td>Bibtex Key:</td>
<td><?php echo $this->Form->control('bibtexkey', ['label' => '', 'type' => 'text']); ?></td>
</tr>
<tr>
<td>Year:</td>
<td><?php echo $this->Form->control('year', ['label' => '', 'type' => 'text', 'maxLength' => 20]); ?></td>
</tr>
<tr>
<td>Entry Type ID:</td>
<td><?php echo $this->Form->control('entry_type_id', ['label' => '', 'options' => $entryTypes, 'empty' => true]); ?></td>
</tr>
<tr>
<td>Address:</td>
<td><?php echo $this->Form->control('address', ['label' => '', 'type' => 'text', 'maxLength' => 45]); ?></td>
</tr>
<tr>
<td>Annote:</td>
<td><?php echo $this->Form->control('annote', ['label' => '', 'type' => 'text', 'maxLength' => 45]); ?></td>
</tr>
<tr>
<td>Book Title:</td>
<td><?php echo $this->Form->control('book_title', ['label' => '', 'type' => 'text', 'maxLength' => 255]); ?></td>
</tr>
<tr>
<td>Chapter:</td>
<td><?php echo $this->Form->control('chapter', ['label' => '', 'type' => 'text', 'maxLength' => 100]); ?></td>
</tr>
<tr>
<td>Cross Reference:</td>
<td><?php echo $this->Form->control('crossref', ['label' => '', 'type' => 'text', 'maxLength' => 45]); ?></td>
</tr>
<tr>
<td>Edition:</td>
<td><?php echo $this->Form->control('edition', ['label' => '', 'type' => 'text', 'maxLength' => 45]); ?></td>
</tr>
<tr>
<td>How Published:</td>
<td><?php echo $this->Form->control('how_published', ['label' => '', 'type' => 'text', 'maxLength' => 255]); ?></td>
</tr>
<tr>
<td>Institution:</td>
<td><?php echo $this->Form->control('institution', ['label' => '', 'type' => 'text', 'maxLength' => 45]); ?></td>
</tr>
<tr>
<td>Journal:</td>
<td><?php echo $this->Form->control('journal_id', ['label' => '', 'options' => $journals, 'empty' => true]); ?></td>
</tr>
<tr>
<td>Month:</td>
<td><?php echo $this->Form->control('month', ['label' => '', 'type' => 'text', 'maxLength' => 45]); ?></td>
</tr>
<tr>
<td>Note:</td>
<td><?php echo $this->Form->control('note', ['label' => '', 'type' => 'text', 'maxLength' => 45]); ?></td>
</tr>
<tr>
<td>Number:</td>
<td><?php echo $this->Form->control('number', ['label' => '', 'type' => 'text', 'maxLength' => 100]); ?></td>
</tr>
<tr>
<td>Organization</td>
<td><?php echo $this->Form->control('organization', ['label' => '', 'type' => 'text', 'maxLength' => 45]); ?></td>
</tr>
<tr>
<td>Pages:</td>
<td><?php echo $this->Form->control('pages', ['label' => '', 'type' => 'text', 'maxLength' => 45]); ?></td>
</tr>
<tr>
<td>Publisher:</td>
<td><?php echo $this->Form->control('publisher', ['label' => '', 'type' => 'text', 'maxLength' => 100]); ?></td>
</tr>
<tr>
<td>School:</td>
<td><?php echo $this->Form->control('school', ['label' => '', 'type' => 'text', 'maxLength' => 80]); ?></td>
</tr>
<tr>
<td>Title:</td>
<td><?php echo $this->Form->control('title', ['label' => '', 'type' => 'text', 'maxLength' => 255]); ?></td>
</tr>
<tr>
<td>Volume:</td>
<td><?php echo $this->Form->control('volume', ['label' => '', 'type' => 'text', 'maxLength' => 50]); ?></td>
</tr>
<tr>
<td>Publication History:</td>
<td><?php echo $this->Form->control('publication_history', ['label' => '', 'type' => 'text']); ?></td>
</tr>
<tr>
<td>Series:</td>
<td><?php echo $this->Form->control('series', ['label' => '', 'type' => 'text', 'maxLength' => 100]); ?></td>
</tr>
<tr>
<td>OCLC:</td>
<td><?php echo $this->Form->control('oclc', ['label' => '', 'type' => 'number']); ?></td>
</tr>
<tr>
<td>Designation:</td>
<td><?php echo $this->Form->control('designation', ['label' => '', 'type' => 'text']); ?></td>
</tr>
</table>
<legend class="capital-heading"><?= __('Linked Artifacts Data') ?></legend>
<table cellpadding="10" cellspacing="10">
<thead>
<tr>
<th scope="col">Artifact Information</th>
<th scope="col">Artifact ID</th>
<th scope="col">Publication ID</th>
<th scope="col">Exact Reference</th>
<th scope="col">Publication Type</th>
<th scope="col">Publication Comments</th>
</tr>
</thead>
<tbody>
<?php foreach ($publication_merge->artifacts as $key => $artifactsPublication): ?>
<?= $this->Form->input("artifacts.{$key}._id", ['type' => 'hidden', 'value' => $artifactsPublication->id]) ?>
<!-- <?= debug($artifactsPublication) ?> -->
<tr>
<td></td>
<td><?= $this->Html->link($artifactsPublication->_joinData->artifact_id, ['controller' => 'Artifacts', 'action' => 'view', $artifactsPublication->_joinData->artifact_id]) ?></td>
<td><?= $this->Html->link($artifactsPublication->_joinData->publication_id, ['controller' => 'Publications', 'action' => 'view', $artifactsPublication->_joinData->publication_id]) ?></td>
<td><?= $this->Form->input("artifacts.{$key}._joinData.exact_reference", ['label' => '', 'type' => 'text']); ?></td>
<td><?= $this->Form->input("artifacts.{$key}._joinData.publication_type", ['label' => '', 'type' => 'select', 'options' => $publication_type_options]); ?></td>
<td><?= $this->Form->input("artifacts.{$key}._joinData.publication_comments", ['label' => '', 'type' => 'textarea']); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?= $this->Form->submit('Submit', ['class' => 'btn btn-primary']) ?>
<?= $this->Form->end() ?>
</div>