And even more weird, the subpage is sometime created with the good “presentation” template which is ok, but sometime with the default template which is not ok. This seems to be completely random.
This problem make me crazy :-/
This is my snippet (which I include in my template):
<?php
?>
<style>
.honey {
position: absolute;
left: -9999px;
}
</style>
<form class="dashboard-proposalnew repeater" action="<?= $page->url() ?>" method="post" enctype="multipart/form-data">
<div class="form-element">
<label for="title">Title:</label>
<input type="text" id="title" name="title" placeholder="Title" value="" required/>
<?php if( $alert['title'] ) { echo '<span class="alert">' . html( $alert['title'] ) . '</span>'; } ?>
</div>
<div class="form-element">
<label for="description">Description:</label>
<textarea name="description" id="description" placeholder="Present your proposal in few words" required></textarea>
<?php if( $alert['description'] ) { echo '<span class="alert">' . html( $alert['description'] ) . '</span>'; } ?>
</div>
<div class="form-element">
<label for="type">Type:</label>
<select name="type">
<option value="" selected ></option>
<?php
foreach ( $types as $type_value ):
?>
<option value="<?= strtolower( $type_value['type'] ) ?>" <?php e( $proposal_types_key == strtolower( $type_value['type'] ), 'selected' , '' ) ?> ><?= $type_value['type'] ?></option>
<?php
endforeach;
?>
</select>
</div>
<div class="form-element">
<label for="thematic">Thematic:</label>
<select name="thematic">
<option value="" selected ></option>
<?php
foreach ( $thematics as $thematic_value ):
?>
<option value="<?= strtolower( $thematic_value['thematic'] ) ?>" <?php e( $proposal_thematics_key == strtolower( $thematic_value['thematic'] ), 'selected' , '' ) ?> ><?= $thematic_value['thematic'] ?></option>
<?php
endforeach;
?>
</select>
</div>
<div class="form-element" data-repeater-list="speakers">
<div data-repeater-item>
<label for="department">Speakers:</label>
<select name="speaker">
<option value="" selected></option>
<?php
foreach ( $speakers as $speaker_key => $speaker_value ):
?>
<option value="<?= $speaker_key ?>" <?php e( $proposal_thematics_key == $speaker_value, 'selected' , '' ) ?> ><?= $speaker_value ?></option>
<?php
endforeach;
?>
</select>
<input data-repeater-delete type="button" value="Delete"/>
</div>
</div>
<input data-repeater-create type="button" value="Add"/>
<div class="honey">
<label for="genre">If you are a human, leave this field empty</label>
<input type="genre" name="genre" id="genre" placeholder="M./Me." value="<?= !empty($data['genre']) ? $data['genre'] : '' ?>"/>
</div>
<input type="hidden" name="csrf_token_proposalnew" value="<?php echo csrf() ?>">
<button class="button" type="submit" name="proposalnew" value="proposalnew" >Save New Proposal</button>
</form>
This is my controller:
<?php
return function( $site, $pages, $page ) {
$alert = array();
$csrf = '';
$types = array();
$thematics = array();
$speakers = array();
$speakers_form = array();
$presentations_page_uri = '';
$types = !empty( $site->conferenceTypes()->yaml() ) ? $site->conferenceTypes()->yaml() : array();
$thematics = !empty( $site->conferenceThematics()->yaml() ) ? $site->conferenceThematics()->yaml() : array();
// get all users and build a $speakers array: key=usename / value=last + first name
foreach ( $site->users() as $user ):
if ( !empty( $user->firstname() ) && !empty( $user->lastname() ) ):
$name = $user->lastname() . ' ' . $user->firstname();
elseif ( !empty( $user->firstname() ) || !empty( $user->lastname() ) ):
$name = $user->username() . ' - ' . 'Incomplete name, check the user firstname and lastname';
endif;
$speakers[$user->username()] = $name;
endforeach;
// sort speakers by name
asort( $speakers );
// get speakers choosed from the form by the user
$speakers_form = !empty( get('speakers') ) ? get('speakers') : array();
// determine the presentations uri() even if the user changes it
$presentation_objet = $pages->filterBy( 'template' , 'presentations' );
// There is only one page set with the "presentations" template (and it MUST stay like this)
foreach ( $presentation_objet as $presentation_page ):
// The presentation page uri is nedeed to build the path when creating a presentation subpage (see below)
$presentations_page_uri = $presentation_page->uri();
endforeach;
if ( r::is('post') && get('proposalnew') ) {
if ( !empty(get('genre') ) ) {
// lets tell the bot that everything is ok
go( $page->url() );
exit;
}
$data = array(
'title' => strip_tags( esc( get('title') ) ),
'description' => strip_tags( esc( get('description') ) ),
'type' => strip_tags( esc( get('type') ) ),
'thematic' => strip_tags( esc( get('thematic') ) ),
);
$rules = array(
'title' => array('required'),
'description' => array('required'),
'type' => array(),
'thematic' => array(),
);
$messages = array(
'title' => 'Please enter a title, this field is required',
'description' => 'Please enter a description, this field is required',
'type' => '',
'thematic' => '',
);
// some of the data is invalid
if ( $invalid = invalid( $data, $rules, $messages ) ) {
$alert = $invalid;
}
// check the form token
$csrf = get('csrf_token_proposalnew');
if (
!empty( $csrf ) &&
csrf( $csrf ) &&
empty( $alert )
)
{
// everything is ok, let's try to create a new proposal
try {
// Create a new presentation
if ( !empty( $data['title'] ) && !empty( $data['description'] && !empty( $presentations_page_uri ) ) ):
//$new_presentation = $page->create( $presentations_page_uri . '/' . str::slug( $data['title'] ) , 'presentation' , $data );
$new_presentation = page($presentations_page_uri)->children()->create(str::slug( $data['title'] ) , 'presentation' , $data );
endif;
$data = array();
} catch( Exception $e ) {
echo 'Your proposal creation failed: ' . $e->getMessage();
}
try {
// set the structure field "Speakers"
$speakers_update = add_to_structure_speaker( $new_presentation , 'speakers' , $speakers_form );
$success = 'New proposal saved';
} catch( Exception $e ) {
echo 'Your speakers structure field failed: ' . $e->getMessage();
}
if ( $new_presentation && $speakers_update ):
$success = 'New proposal saved';
endif;
}
}
return array(
'types' => $types,
'thematics' => $thematics,
'speakers' => $speakers,
'alert' => $alert,
'data' => $data,
'success' => $success,
);
};
/**
* Add a new element to a kirby structure field
* @param string $page
* @param string $field
* @param array $data
*/
function add_to_structure_speaker( $page, $field, $data = array() ) {
$fieldData = $page->$field()->yaml();
$fieldData[] = $data;
$fieldData = yaml::encode( $fieldData );
try {
$update_structure = $page->update( array( $field => $fieldData ) );
return $update_structure;
} catch( Exception $e ) {
return $e->getMessage();
}
}
There is just a little difference with my previous code post. page(uri) is replaced by $page in the “add_to_structure_speaker” function parameter, but the result is the same.