I have an order form to purchse a voucher but for some reason now when I click phurcase it displays a blank screen. I cant see what has changed and why the view is not being passed the information from the controller.
Vourchers form
<h2>Vouchers</h2>
<?php
foreach($vouchers as $v){
?>
<div id="voucher_box" class="add_shadow column span-8">
<h3><?=$v['Voucher']['title'];?></h3>
<p>
<?=$v['Voucher']['description'];?>
</p>
<?php
echo $this->Form->create('Voucher',array('id'=>'ResVoucherForm','url'=>'/res/voucher'));
echo $this->Form->input('slug',array('type'=>'hidden','value'=>$v['Voucher']['slug']));
?>
<select id="VoucherPrice" name="data[Voucher][price]">
<? $prices = explode(',',$v['Voucher']['prices'])?>
<? foreach($prices as $price){?>
<option value="<?=$price?>">€ <?=$price?></option>
<? } ?>
</select>
<div class="submit"><input type="submit" id="check_rates" value="Purchase this" class="ui-button ui-widget ui-state-default ui-corner-all" /></div>
</form>
</div>
<?
}
?>
Controller
function voucher() {
$this->layout = '360';
$msg[0] = array(); // 0 = bad messages
$msg[1] = array(); // 1 = good messages
$total_price = 0.00;
if(isset($data['Voucher'])) { $this->data['Voucher'] = $data['Voucher']; }
if(isset($this->data['Voucher'])) {
// if we have posted a voucher purchase: add it to session array
if(isset($this->data['Voucher']['slug'])){
$slug = $this->data['Voucher']['slug'];
$voucher = $this->getVoucher($slug);
$voucher['Voucher']['price'] = $this->data['Voucher']['price'];
$vouchers = $this->Session->read('Res.Vouchers'); // read existing voucher orders
if(is_array($vouchers) && isset($voucher['Voucher'])){
$temp['id'] = $voucher['Voucher']['id'];
$temp['title'] = $voucher['Voucher']['title'];
$temp['description'] = $voucher['Voucher']['description'];
$temp['slug'] = $voucher['Voucher']['slug'];
$temp['price'] = $this->data['Voucher']['price'];
$vouchers[] = $temp;
}
$this->Session->write('Res.Vouchers',$vouchers);
} else {
$vouchers = $this->Session->read('Res.Vouchers'); // read existing voucher orders
}
$this->set('voucher_orders', $vouchers);
}
This next view displays blank, I do not know how to test the information in the controller
<?php
/*
if voucher show
*/
if (isset($voucher)) {
?>
<div id="voucher_box" class="add_shadow column span-8">
<h3><?=$voucher['Voucher']['title'];?></h3>
<p>
<?=$voucher['Voucher']['description'];?>
</p>
<?php
echo $this->Form->create('Voucher',array('id'=>'ResVoucherForm','url'=>'/res/voucher'));
echo $this->Form->input('slug',array('type'=>'hidden','value'=>$voucher['Voucher']['slug']));
?>
<select id="VoucherPrice" name="data[Voucher][price]">
<? $prices = explode(',',$voucher['Voucher']['prices'])?>
<? foreach($prices as $price){?>
<option value="<?=$price?>">€ <?=$price?></option>
<? } ?>
</select>
<div class="submit"><input type="submit" id="check_rates" value="Purchase this" class="ui-button ui-widget ui-state-default ui-corner-all" /></div>
</form>
</div>
<?
}
// end if voucher show
?>
Upadate Error Returned #######################################################
Notice (8): Undefined index: id [APP/controllers/res_controller.php, line 739]
Notice (8): Undefined index: title [APP/controllers/res_controller.php, line 740]
Notice (8): Undefined index: description [APP/controllers/res_controller.php, line 741]
Notice (8): Undefined index: slug [APP/controllers/res_controller.php, line 742]
Array
(
[0] => Array
(
[id] =>
[title] =>
[description] =>
[slug] =>
[price] => 100
)
)
In the view, you have this around the whole HTML:
if (isset($voucher)) {
// ...
}
Meaning: display voucher information if there is a voucher, and do not display anything otherwise.
Now, in your controller, you don't seem to be passing a voucher variable to the view (which should be done with $this->set('varname', $var);
So, your view does not get any data, thus it does not display anything.
This could explain your issue. But if the screen is completely blank (not even the layout displays), then you must enable error logging to check what's going on.
You are setting 'voucher_orders' to your view not 'voucher' the name of the variable in the view is always the string passed in the set method. Also I don't quite understand what you are doing in the controller with the $data variable, where does it come from? Also it's redundant doing $this->data['Voucher'] = $data['Voucher'] and the checking $this->data isset if you already checked if $data is set. You might be overwriting your $this->data array, what you are doing is not necessary since the view already gives you a populated $this->data if its a form submission.
You should really try doing some tutorials and reading up a little before jumping in, you seem to not properly understand the CakePHP structure and workflow.
Thanks for all your help. By using the pr() or debug() in the controller I found the problem. It was in the function that was getting called on the line $voucher = $this->getVoucher($slug);. I now have a better understanding of cakephp.
Related
I'm using a WP_Query call to populate a slider with the thumbnails of all of my 'added' Custom Post Types, but the first and last posts from the results both appear three times in the loop.
I've tried echoing an int within the loop to identify where it's going wrong, and the int doesn't appear in every loop either, so these posts are somehow being called separately. I've been over my code repeatedly but cannot figure out where this is going wrong.
<?php
$args = array(
'post_type' => 'added', // enter your custom post type
'post_status' => 'publish',
'posts_per_page' => 4,
'orderby' => 'title',
'order' => 'ASC',
);
$added_query = new WP_Query( $args );
$i = 0;
// if( $added_query->have_posts() ):
echo '<div id="slider" class="add-something container slideshow-container slider fadeInUp">';
echo '<h2>FOR OVER 20 YEARS WE'VE ADDED SOMETHING TO</h2>';
echo '<div class="slider-wrapper">';
echo '<div id="slides" class="slides">';
while( $added_query->have_posts() ):
$added_query->the_post();
echo $i;
// global $post;
?>
<div class="added-link slide" style="width:150px;">
<div class="added-logo">
<?php echo get_the_post_thumbnail(get_the_ID(),'medium'); ?>
</div>
</div>
<?php
wp_reset_postdata();
$i++;
endwhile;
echo '</div>';
echo '</div>';
echo '</div>';
// endif;
?>
This code results in:
Duplicate posts interrupting the array
There are no other WP_Query calls elsewhere in the page template. How can I get rid of these extra slides if they aren't produced by the while loop? And why are they interrupting my loop like this?
Edit: Following #Aurel 's advice I've tried adding some styling to the "added-logo" class, and it gets applied to all of the images.
0 and 3 values seems to have a bigger image than 1 and 2. Can you add a style on added-logo CSS class ? or like :
<div class="added-logo" style="border:solid 1px #ff0000;">
<?php echo get_the_post_thumbnail(get_the_ID(),'medium'); ?>
</div>
for debugging purpose only and post the image ? thanks
I just followed a tag tutorial (https://book.cakephp.org/3.0/en/tutorials-and-examples/cms/tags-and-users.html) on the Red Velvet Cookbook. I was successful in adding tagging to my website. Though I feel it needs a couple more things. The comma separated list of tags is just that, a list. I would prefer a list of links. The links would obviously link to a list of posts that are tagged with the same tag. This list already exists thanks to the tutorial. The url looks like http://localhost:8765/story/tagged/cats/
I have fiddled with the html helper to try and create links but I am unsure how to do this with an array. Any leads or help would be greatly appreciated.
This is the line in my template that shows the list of tags
<p><b>Tags:</b> <?= h($story->tag_string) ?></p>
This is the function that gets the tag_string
class Story extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* #var array
*/
protected $_accessible = [
'*' => false,
'tag_string' => true
];
protected function _getTagString()
{
if (isset($this->_properties['tag_string'])) {
return $this->_properties['tag_string'];
}
if (empty($this->tags)) {
return '';
}
$tags = new Collection($this->tags);
$str = $tags->reduce(function ($string, $tag) {
return $string . $tag->name . ', ';
}, '');
return trim($str, ', ');
}
}
In your $story entity you have tags property, which you already used in computed field tag_string. To get separated tags, you need to iterate over it in a template, eg:
<ul>
<?php foreach($story->tags as $tag): ?>
<li><?= $tag->title ?></li>
<?php endforeach; ?>
</ul>
Assuming you have a method in your StoriesController named tagged, which accepts one parameter: tag title, you can construct link using HtmlHelper for each tag:
<ul>
<?php foreach($story->tags as $tag): ?>
<li>
<?= $this->Html->link($tag->title, [
"controller" => "Stories",
"action" => "tagged",
$tag->title
], [
"class" => "your-tag-link-class" //second array is for properties, in case you would like to add eg class for these links to style them using css.
]) ?>
</li>
<?php endforeach; ?>
</ul>
My Problem I can't get my dynamic checkboxes to save properly in from my edit.blade, they only work if the values are 1, if an unchecked checkbox is submitted via hidden field it will overwrite the next set of checkbox checked values.
My Code
I have a crud resource that takes orders, the form in the create.blade itself has a bunch of dynamic fields that add a new product to the order via 'add-new' button that clones the product fields.
Part of that form is a bunch of days checkboxes that work fine and are stored correcly.
Where I'm Getting Stuck
I've made an edit.blade to be used to correct any mistakes that would be made while creating an order.
To call back the section that refers to the dates checkboxes I've used the following blade syntax (I know its different from create, mainly due to me trying to fix the problem)
#foreach($orders as $orderkey => $order)
#foreach($days as $day)
{{ Form::hidden($day.'[]', 0, array('id'=> $day.'_hidden_'.$orderkey, 'class' => 'is-checkradio')) }}
{{ Form::checkbox($day.'[]', 1, $order->{$day}, array('id'=> $day.'_'.$orderkey, 'class' => 'is-checkradio')) }}
<label for="<?php echo $day.'_'.$orderkey; ?>"><?php echo $day; ?></label>
#endforeach
#endforeach
OrderController - Update
I've had to use the following in my controller to get the fields to update however whenever a checkbox is left unchecked it will overwrite the next checked value.
$customer = Customer::find($id);
foreach($customer->orders as $key => $order){
$Monday[] = $request->Monday[$key];
};
$updates = array(
'Monday' => $Monday,
);
foreach($updates['orders'] as $k => $update){
$update_order->Monday = $updates['Monday'][$k];
$update_order->save();
};
This part:
foreach($customer->orders as $key => $order){
$Monday[] = $request->Monday[$key];
};
Is creating an array where if the existing data is true and the new data is true, save it. Otherwise delete it. That means any checkboxes that have been deselected will be captured, but any newly checked checkboxes won't be. Is this your intention?
Why not just do:
$updates = array(
'Monday' => $request->Monday,
);
I may not have fully understood your question so please comment and/or amend the Q if you need to clarify further,
Found out how to fix it from Unchecked checkbox returning null value
I needed to add my $orderkey to the name []
So in the end this worked:
#foreach($days as $day)
{{ Form::hidden($day.'['.$orderkey.']', null, array('id'=> $day.'_hidden_'.$orderkey, 'class' => 'is-checkradio')) }}
{{ Form::checkbox($day.'['.$orderkey.']', 1, $order->{$day}, array('id'=> $day.'_'.$orderkey, 'class' => 'is-checkradio')) }}
<label for="<?php echo $day.'_'.$orderkey; ?>"><?php echo $day; ?></label>
#endforeach
I've customized the edit profile view using template.php and user-profile-form.php
All shows up correctly but the Submit (and Delete) button..
I'm using Adaptive Theme and I've modified like this :
template.php
function adaptivetheme_theme(&$existing, $type, $theme, $path) {
return array(
'user_profile_form' => array(
'template' => 'templates/user-profile-form',
'render element' => 'form',
),
);
}
function adaptivetheme_preprocess_user_profile_form(&$vars) {
$vars['form']['account']['name']['#description'] = t('blabla');
$vars['form']['submit']['#value'] = t('Save profile');
$vars['form']['delete']['#value'] = t('Delete account');
$vars['account'] = drupal_render($vars['form']['account']);
$vars['theme_select'] = drupal_render($vars['form']['theme_select']);
$vars['picture'] = drupal_render($vars['form']['picture']);
$vars['signature_settings'] = drupal_render($vars['form']['signature_settings']);
$vars['contact'] = drupal_render($vars['form']['contact']);
$vars['timezone'] = drupal_render($vars['form']['timezone']);
$vars['submit'] = drupal_render($vars['form']['submit']);
$vars['delete'] = drupal_render($vars['form']['delete']);
}
then in the user-profile-form.tpl.php :
<div id="user-profile-form">
<?php echo $account; ?>
<?php echo $timezone; ?>
<?php echo $submit; ?>
<?php echo $delete; ?>
</div>
The edit form of the account shows correctly. I've tried adding/removing variables successfully (ie the $timezone) but the submit/delete are missing.
I don't know what's wrong..
I've tried to change the name of the variables 'submit' and 'delete' but still no button shows up. Of course I've cleared the cache every times needed (and not).
I have no JS hiding the buttons neither..
I render this form through a custom block in a Panel :
<?
module_load_include('inc', 'user', 'user.pages');
global $user;
print drupal_render(drupal_get_form('user_profile_form', $user));
?>
Maybe a problem with Panels ???
Any idea is appreciated :)
Thx for reading
Erwan
I forgot the "[action]".. :
$vars['submit'] = drupal_render($vars['form']['actions']['submit']);
$vars['cancel'] = drupal_render($vars['form']['actions']['cancel']);
And 'Delete' button didn't show up at first because it's called "cancel", and its #access param was sent to FALSE. Thx DPM ;)
Now, the problem is that when I trigger the submit button, the form is not sent, it justs reload he page. I will update if I manage to solve that too.
The page is only reloading because you forget to render the hidden form elements. To do so in your template preprocess you can use something like that :
function THEME_preprocess_user_profile_form(&$variables) {
$hidden = array();
foreach(element_children($variables['form']) as $key)
{
$type = $variables['form'][$key]['#type'];
if($type == "hidden" || $type == "token"){
$hidden[] = $variables['form'][$key];
}
}
$variables['hidden'] = $hidden;
//Dont forget to report your variables like you already did ...
}
Then when it s done render the $hidden variable in your template file
<?php print render($hidden);?>
And there you go !
For reference, please visit this page here. When trying to get a view display on one particular model, I am getting an undefined index error. Specifically, any data from my Coupon model. Here is my controller code:
public function seafood() {
$this->paginate['Restaurant']=array(
'limit'=>9,
'order' => 'RAND()',
'contain'=>array(
'User'=>array(
'id', 'user_name'),
'Coupon'=>array(
'id','description','expires','end_date','promo_code','restaurant_id')
),
'conditions'=>array(
'Restaurant.active'=>1,
'Restaurant.seafood'=>'Seafood'
)
);
$data = $this->paginate('Restaurant');
$this->set('seafood', $data);
when I debug($seafood) in my view, all data for Coupon shows, so I know it is correctly pulling data and associating it with my Restaurant model. However, when I create a foreach loop with my $seafood array, I get nothing but undefined index errors for anything Coupon-related. What's weird is that I also have my controller pulling from the User model and anything I call up from that model in the view gets rendered. Here is my view code:
<?php foreach ($seafood as $res) { ?>
.....irrelevant code.....
<p><?php if($res['Coupon']['description'] !=''){
echo $this->Text->truncate($res['Coupon']['description'], 200, array('ending'=>'...', 'exact'=>false) );
}
else echo 'Sorry, a description of this restaurant\'s promotion is not available. <br><br><br>';
?><em> (read more -->)</em></p>
<br />
<div>
<span style="margin-left:36px;">Promo Code: <span style="font-style:bold; color:#FF0000;"><?php echo $res['User']['user_name']; ?></span></span>
<span style="margin-left:24px;">Print</span>
<?php } ?>
......more irrelevant code.....
I have tried removing the containable behavior from the array but the results are the same. I should point out that when the debug array prints, it goes in order: Restaurant, User, Coupon. Is cake somehow losing the Coupon array because it is 3rd? Or is my view code just screwy?
Looks like Restaurant hasMany Coupon so Coupon is an indexed array. You'll need a nested for loop.
foreach ($seafood as $res) {
//irrelevant
foreach ($res['Coupon'] as $coupon) {
if($coupon['description'] !=''){
//do stuff
}
}
}