Custom Fields - Repeater dropdown - list only unique & not blank values - arrays

Here's the thing that I'm using the ACF repeater subfield (firma) to store some data. Usually the user is typing here his parent company name like: google, alibaba, sodexo etc. So it might happen that in multiple posts, the value of this field will be the same. At the moment I have following code:
$args = array(
'post_type' => 'opencourses',
'meta_key' => 'terminy_warsztatow'
);
$the_query = new WP_Query($args);
if ($the_query->have_posts()):
echo '<select type="text" class="form-control" name="filtr_lokalizacja">';
while ($the_query->have_posts()) : $the_query->the_post();
if(have_rows('terminy_warsztatow')):
while (have_rows('terminy_warsztatow')) : the_row();
// display your sub fields
$filtr_var = get_sub_field('firma');
echo '<option value="'. $filtr_var .'">';
echo $filtr_var;
echo '</option>';
endwhile;
else :
// no rows found
endif;
endwhile;
echo '</select>';
endif;
And it works - meaning: it shows all typed values. But instead of showing only UNIQUE values it generates a list similar to this:
Google
Alibaba
Google
Sodexo
Sodexo
Tesla
Tesla
Sodexo
How to avoid showing same values and hide empty as well? I know that there is php function array_unique but I was unable to implement that. I've done sth like:
$filtr_var = get_sub_field('firma');
$result = array_unique($filtr_var);
echo $result;
but then it shows no values at all.

I assume that "firma" is simple text input type in repeater. if so then arrya_unique function won't work for string output.
you need to save each value in array and then use in_array function to make it unique.
see below code.
$args = array(
'post_type' => 'opencourses',
'meta_key' => 'terminy_warsztatow'
);
$the_query = new WP_Query($args);
if ($the_query->have_posts()):
echo '<select type="text" class="form-control" name="filtr_lokalizacja">';
while ($the_query->have_posts()) : $the_query->the_post();
if(have_rows('terminy_warsztatow')):
// $PreValue = array();
while (have_rows('terminy_warsztatow')) : the_row();
// display your sub fields
$filtr_var = get_sub_field('firma');
// compare current value in saved array
if( !in_array( $filtr_var, $PreValue ) )
{
echo '<option value="'. $filtr_var .'">';
echo $filtr_var;
echo '</option>';
}
// save value in array
$PreValue[] = $filtr_var;
endwhile;
else :
// no rows found
endif;
endwhile;
echo '</select>';
endif;
Hope this will help you!
Enjoy

Related

Codeigniter form populate with db results not working

I have been trying for days now using the form class to populate the text fields from my database. I have also been searching to find out how to do it without any luck.
Please could somebody take a look at my code and tell me what I'm doing wrong.
Model
//This function brings up the selected users information for editing.
public function edit_user($id)
{
$this->db->select('id, email, name, lastname, homeaddress, posteladdress,
mobile, hometel, idnum');
$this->db->where('id', $id)->limit(1);
$query = $this->db->get('user');
return $query->result();
}
Controller
public function get_user_edit($id)
{
$this->load->helper('form');
$this->load->model('model_users'); //Load the user model
//Get the database results from the model
$data['results'] = $this->model_users->edit_user($id);
foreach ($data['results'] as $key => $row)
{
$data['results'] = array( 'id' => $row->id,
'email' => $row->email,
'name' => $row->name,
'lastname' => $row->lastname,
'homeaddress' => $row->homeaddress,
'posteladdress' => $row->posteladdress,
'mobile' => $row->mobile,
'hometel' => $row->hometel,
'idnum' => $row->idnum);
}
$this->load->view('edit_user', $data);
}
View
<div id="body">
<p>Edit user information.</p>
<?php
echo form_open('user_admin/user_update', $results);
echo validation_errors();
echo "<p><lable>Email:</lable>";
echo form_input('email', set_value('email'));
echo "</p>";
echo "<p><lable>Name:</lable>";
echo form_input('name', set_value('name'));
echo "</p>";
echo "<p>";
echo form_submit('edit_submit', 'Update');
echo "</p>";
echo form_close();
?>
I keep getting this error
A PHP Error was encountered
Severity: 4096
Message: Object of class stdClass could not be converted to string
Filename: helpers/form_helper.php
Line Number: 1010
First thing. You're expecting a single row to be returned from the database, right? But you're looping through the result in your controller. Instead of doing that in your model:
return $query->result();
do this:
return $query->row();
and remove the foreach loop from your controller (it even has an unused $key var in there). You'll end up having cleaner and shorter code. Only if you're getting a single row, which seems to be the case.
Moving on.
Have you read the documentation here: https://ellislab.com/codeigniter/user-guide/helpers/form_helper.html ?
form_open('user_admin/user_update', $results); - what are you trying to do here?
You use the second parameter to pass attributes to the opening tag. Now looking at your code, your $results array has values for each field. Doesn't make much sense to push all this into the form opening tag, does it?
Field rendering with the correct values.
This is an example from the documentation how to configure and render an input field:
$data = array(
'name' => 'username',
'id' => 'username',
'value' => 'johndoe',
'maxlength' => '100',
'size' => '50',
'style' => 'width:50%',
);
echo form_input($data);
So, your email input should be formatted having the minimal config like that:
$data = array(
'name' => 'email',
'value' => $results['email']
);
echo form_input('email', $data);
On validation (in your user_update() method in user_admin controller), you'll have to do some logic to capture the value you're validating. So you'll need something like:
$results['email'] = set_value('email');
Hope that makes sense!
Thank you very much for your help. I'm sure you must have realised that I'm new to Codeigniter, but with your help I was able to sort out the problem that I had.
I changed the query to return only the one result that it found like you suggested
return $query->row();
and you were right I didn't need the foreach loop to populate an array to pass to the view.
Thanks for pointing out that I was trying to pass the results from db as the attribute for the form.:)
I added my code below for anybody that come across my question with the same problem. Maybe it will help them.
My controller
public function get_user_edit($id)
{
$this->load->model('model_users'); //Load the user model
//Get the database results from the model
$data['results'] = $this->model_users->edit_user($id);
$this->load->view('edit_user', $data);
}
My model
//This fetches the selected users information for editing.
public function edit_user($id)
{
$this->db->select('id, email, name, lastname, homeaddress, posteladdress,
mobile, hometel, idnum');
$this->db->where('id', $id)->limit(1);
$query = $this->db->get('user');
return $query->row();
}
My view
<div id="container">
<h1>Edit user</h1>
<div id="body">
<p>Edit user information.</p>
<?php
echo form_open('user_admin/user_update');
echo validation_errors();
echo form_hidden('id', $results->id);
echo "<p><lable>Email:</lable>";
echo form_input('email', $results->email);
echo "</p>";
echo "<p><lable>Name:</lable>";
echo form_input('name', $results->name);
echo "</p>";
echo "<p><lable>Last name:</lable>";
echo form_input('lastname', $results->lastname);
echo "</p>";
echo "<p><lable>Home address:</lable>";
echo form_input('homeaddress', $results->homeaddress);
echo "</p>";
echo "<p><lable>Postal address:</lable>";
echo form_input('posteladdress', $results->posteladdress);
echo "</p>";
echo "<p><lable>Mobile number:</lable>";
echo form_input('mobile', $results->mobile);
echo "</p>";
echo "<p><lable>Home telephone:</lable>";
echo form_input('hometel', $results->hometel);
echo "</p>";
echo "<p><lable>ID number:</lable>";
echo form_input('idnum', $results->idnum);
echo "</p>";
echo "<p>";
echo form_submit('edit_submit', 'Update');
echo "</p>";
echo form_close();
?>
</div>

how to display result in view part in cakephp

public function outofstock(){
$this->loadModel('Store');
$store=$this->Store->find('all',array('fields' => array('Store.store_shortcode')));
$this->set('store',$store);
foreach($store as $store):
$store_shortcode= $store['Store']['store_shortcode'];
$item=$this->Item->find('all',array('conditions' => array($store_shortcode.' =' => 0 )));
foreach($item as $item1){
echo $item1['Item']['item_name'];
echo $store_shortcode;
}
endforeach;
$this->set('item',$item);
}
This is my controller part code .
I want to display echo $item1['Item']['item_name'] , $store_shortcode in view part . Actually in controller its displaying properly but in view part its not displaying . store_shortcode is GLF,DLLK,MKL . Item Name is ADASHG , GRAFGHJ, Store names or columns of item table and store_name of store table .
Controller ($items[ ]):
public function outofstock(){
$this->loadModel('Store');
$store=$this->Store->find('all',array('fields' => array('Store.store_shortcode')));
$this->set('store',$store);
foreach($store as $store):
$store_shortcode= $store['Store']['store_shortcode'];
$items[] =$this->Item->find('all',array('conditions' => array($store_shortcode.' =' => 0 )));
endforeach;
$this->set('items',$items);
}
In the view.ctp:
foreach($items as $item){
echo $item['Item']['item_name'];
}
But generally you have a a bad approach,
Do hasMany relational between the Store and Item model, and then easily with the help of a one query take data.
Use this in view file
foreach($store as $store):
$store_shortcode= $store['Store']['store_shortcode'];
$item=$this->Item->find('all',array('conditions' => array($store_shortcode.' =' => 0 )));
foreach($item as $item1){
echo $item1['Item']['item_name'];
echo $store_shortcode;
}
endforeach;

Save array from drop-down menu in Wordpress

I have successfully pulled a custom post type through into a drop-down that is in a custom meta box. However, when displaying it on the front end I would like to also provide a link to the actual post, not just the name of the post. So I am guessing I need to save this as an array? Is this possible through a drop-down? Confused on how I should approach this. Any help is greatly appreciated.
Here is what I have so far:
// Add Meta Box To Select Overseeing Pastor
add_action('admin_init', 'ministry_select_add_meta');
function ministry_select_add_meta(){
add_meta_box('ministry_select_post', __('Overseeing Pastor'), 'ministry_select_meta', 'ministry', 'side');
}
function ministry_select_meta( $post ) {
$values = get_post_custom( $post->ID );
$selected = isset( $values['pastor_select'] ) ? esc_attr( $values['pastor_select'][0] ) : '';
wp_nonce_field( 'my_meta_box_nonce', 'meta_box_nonce' );
?>
<select name="pastor_select">
<?php
$args = array(
'post_type' => 'employee',
'position' => 'pastor'
);
$pastorList = new WP_Query($args); while ($pastorList->have_posts()) : $pastorList->the_post();
$is_selected = (get_the_title() == $selected) ? 'selected="selected"' : '';
echo '<option value="'.get_the_title().'" '.$is_selected.'>'.get_the_title().'</option>';
endwhile; wp_reset_postdata();
?>
</select>
<?php
}
add_action( 'save_post', 'ministry_select_save' );
function ministry_select_save( $post_id )
{
// Stop If Autosaving
if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
// Stop If Nonce Can't Be Verified
if( !isset( $_POST['meta_box_nonce'] ) || !wp_verify_nonce( $_POST['meta_box_nonce'], 'my_meta_box_nonce' ) ) return;
// Stop If Unauthorized User
if( !current_user_can( 'edit_post' ) ) return;
// Make Sure Data Is Set Then Save
if( isset( $_POST['pastor_select'] ) )
update_post_meta( $post_id, 'pastor_select', esc_attr( $_POST['pastor_select'] ) );
}
To get the link of a Post you can use the get_permalink function
<?php $permalink = get_permalink( ); ?>
or like this if you are outside the Loop
<?php $permalink = get_permalink( $post->ID ); ?>
You can use that to print it in any place on your HTML code.
If what you want is go to the Post URL when the Post Title is selected in the Drop Down you can use JavaScript code to do that, doing something like:
<select name="pastor_select" onchange='location=this.options[this.selectedIndex].value;'>
<?php
$args = array(
'post_type' => 'employee',
'position' => 'pastor'
);
$pastorList = new WP_Query($args); while ($pastorList->have_posts()) : $pastorList->the_post();
$is_selected = (get_the_title() == $selected) ? 'selected="selected"' : '';
echo '<option value="'.get_permalink( ).'" '.$is_selected.'>'.get_the_title().'</option>';
endwhile; wp_reset_postdata();
?>
</select>
If what you want is save some POST information, is recommended save the ID of the POST, so later you can retrieve any data for that POST, what if you want to store permalink and title you can combine the functions get_permalink( ); and get_the_title(); in the select "value" attribute.
So I came up with a different solution. Instead of trying to save an array, I just saved the post ID which would allow me access to the title of the post as well as the permalink.
This is my modified code
<select name="pastor_select">
<?php
$args = array(
'post_type' => 'employee',
'position' => 'pastor'
);
$pastorList = new WP_Query($args); while ($pastorList->have_posts()) : $pastorList->the_post();
$employeeID = get_the_ID(); // THIS FIXED THE PROBLEM
$is_selected = ($employeeID == $selected) ? 'selected="selected"' : '';
echo '<option value="'.$employeeID.'" '.$is_selected.'>'.get_the_title().'</option>';
endwhile; wp_reset_postdata();
?>
</select>
And this is how I am calling it on the front end
<?php
$id = $post_meta_data['pastor_select'][0];
echo '<a href="'.get_permalink($id).'">';
echo get_the_title($id);
echo '</a>';
?>

Create a custom loop with post IDs taken from Magic Fields 2 duplicate text fields

I'm trying to create a custom loop with content related to specific post IDs whose numbers I'm getting from a Magic Fields duplicate text field called "reference_posts".
When I echo $testvalue; it outputs the correct listing of posts "20432,43242,34253," but when I try to output it inside the array I only get the first value repeated over and over "20432,20432,20432,".
I'm guessing the problem is that I have to envelope the second foreach within the first but I'm not managing to do that.
Can anyone help me out?
<?php
$value = get_field ('reference_posts') ;
foreach ( $value as $my_val ) {
$testvalue = $my_val . ",";
echo $testvalue;
$post_idarray = array( 'post__in' => array( $testvalue ) );
$postspecial = get_posts($post_idarray);
}
foreach( $postspecial as $post ) :
setup_postdata($post);
?>
<div>my content</div>
<?php endforeach; ?>
Thanks in advance!
Got it with:
<?php
$value = get_field ('reference_posts') ;
foreach ( $value as $my_val );
$args = array( 'include' => $value );
$myposts = get_posts( $args );
foreach( $myposts as $post ) : setup_postdata($post); ?>
<div>my content</div>
<?php endforeach; ?>

Count associated records with tree model (full depth)

We have two models. Ebooks HABTM Tags, where tags follows the tree behavior.
For each tag we need two numbers. First, the number of ebooks associated to the tag, and secondly the number of ebooks associated to the tag + the number of associated ebooks for each descendant.
How can we get the tags with these numbers in an array in tree format?
Thank you very much for any help.
Update: There is a datetime parameter Ebook.published which defines when the book is to be counted or not. All the ebooks that have codeEbook.published < NOW() should be counted.
Cake has no basic support for this. You will need to do the calculations on the fly or create your own counter cache with custom code to update. This is messy.
I'd suggest overriding the beforeSave() and afterSave() function in your Ebooks controller. If updating, grab the current existing set of tags associated with the Ebook in your beforeSave(). In the afterSave() grab the new set of tags and merge it with the previous set. If there are any changes, iterate through all the tags and call $this->Tag->getPath($id) to get a list of all the ancestors. You'll now have all the tags that were affected by the save. You can now iterate through them and update the counts.
Actually, I found a simpler solution since I already have build the function that returns the tags tree. I used a query for each tag to get the actual count of that moment. Here is what I 've build. Feel free to use it according your needs.
In Tag model
// Returns the number of published ebooks of selected tag
function count_direct_published($tag_id = 0){
$temp = $this->query('SELECT count(*) as count FROM ebooks_tags LEFT JOIN ebooks ON ebooks_tags.ebook_id = ebooks.id WHERE ebooks.published < NOW() AND ebooks_tags.tag_id = '.$tag_id);
return $temp[0][0]['count'];
}
// Returns an array in tree format with $id tag and all his children
// $id = 0 start from the top (parent_id = null), or, from $id = the top's tag id
// $limit = boolean (default false)
// $level = Is the limit of depth applied only if $limit = true
// $ext = true Means this is the first time the function is called
// You can run tree_builder(), returns all the tree,
function tree_builder($id = 0, $limit = false, $level = 1, $ext = 1){
if($ext == 1){
$ext = 0;
$undo = true;
}else{
$undo = false;
}
$this->recursive=-1;
$this->contain('EbooksTag');
$var = array();
$count_all = 0;
// If limit = too big , exit
if($limit !== false && $level > $limit){
return '';
}
// Or else,
// If $id=0, find all the children
if($id == 0){
$tags = $this->find('all',array('conditions'=>array( 'Tag.parent_id IS NULL'), 'order'=>array('Tag.gre')));
// If $id!=0 && runs internally
}elseif($id != 0 && !$undo ){
$tags = $this->find('all',array('conditions'=>array( 'Tag.parent_id'=>$id ), 'order'=>array('Tag.gre')));
}
// If $id!=0 && is called from outside
elseif($id != 0 && $undo){
$tags = $this->find('all',array('conditions'=>array( 'Tag.id'=>$id )));
}
foreach($tags as $key => $tag){
$var[] = $tag;
$next = $this->tree_builder($tag['Tag']['id'], $limit, $level+1, $ext);
end($var); // move the internal pointer to the end of the array
$last_key = key($var); // fetches the key of the element pointed to by the internal pointer
$var[$last_key]['children'] = $next['var'];
$counter_direct = $this->count_direct_published($id);
$var[$last_key]['Tag']['count_all'] = $next['count_all']+$counter_direct;
$count_all += $var[$last_key]['Tag']['count_all'];
}
if( $undo )
{
return $var;
}else{
return array('count_all'=> $count_all, 'var' => $var);
}
}
In tags_controller.php
$this->set('tags', $this->Tag->tree_builder());
In the view
<?php foreach($tags as $tag){?>
<?php // Ο Γονέας σε dropdown box ?>
<div class="main-categ">
<?php echo $tag['Tag']['gre']; ?>
<?php echo $html->image('layout/arrows.png', array('alt'=> "Expand")); ?>
</div>
<div class="collapse">
<?php // Τα στοιχεία του γονέα ?>
<div class="tag-1">
<span class="tag-1">
<?php // Αν ?>
<?php if($tag['Tag']['count_direct']>0){
// Display link
echo $html->link($tag['Tag']['gre'],array('action'=>'view',$tag['Tag']['id']));
echo ' ('.$tag['Tag']['count_direct'].')';
}else{
// Display text
echo $tag['Tag']['gre'];
} ?>
</span>
<?php echo $html->link( 'view all' ,array('action'=>'view_all',$tag['Tag']['id'])); ?>
(<?php echo $tag['Tag']['count_all']; ?>)
</div>
<?php // Για κάθε πρώτο παιδί ?>
<?php foreach($tag['children'] as $tag_1){ ?>
<div>
<span class="tag-2">
<?php if($tag_1['Tag']['count_direct']>0){
// Display link
echo $html->link($tag_1['Tag']['gre'],array('action'=>'view',$tag_1['Tag']['id']));
echo ' ('.$tag_1['Tag']['count_direct'].')';
}else{
// Display text
echo $tag_1['Tag']['gre'];
} ?>
</span>
<?php echo $html->link( 'view all' ,array('action'=>'view_all',$tag_1['Tag']['id'])); ?>
(<?php echo $tag_1['Tag']['count_all']; ?>)
<?php // Τα δεύτερα παιδιά ?>
<?php $i=0; ?>
<?php foreach($tag_1['children'] as $tag_2){ ?>
<?php if($i==0){ echo '<ul class="split">'; $i++; } ?>
<li>
<?php if($tag_2['Tag']['count_direct']>0){
// Display link
echo $html->link($tag_2['Tag']['gre'],array('action'=>'view',$tag_2['Tag']['id']));
echo ' ('.$tag_2['Tag']['count_direct'].')';
}else{
// Display text
echo $tag_2['Tag']['gre'];
} ?>
</li>
<?php } ?>
<?php if($i==1) echo '</ul>'; ?>
<div class="clear"></div>
</div>
<?php } ?>
</div>
Perhaps its not the best solution but it works. Hope that helps

Resources