Drop all unique title entries in array - php

I have a database of 'post titles' containing a lot of duplicates, sometimes with more than 4 posts with the same title.
I want to build an array that gets the ID + Title of every duplicate entry.
$titles = array();
$duplicates = array(); //should be multi-dimensional array containing ID and title of each duplicate entry
//while statement
if (!in_array($post_title, $titles)){
array_push( $titles, $post_title) );
} else {
array_push( $duplicates, $post_title) );
}
//end while
The problem with this is that my $duplicates array only contains the 'second' entry, or the 'duplicate' - I want to store both in the same array. How can I do this using something like array_diff or merge or similar?
I.e. If two posts contain the same title, I want both of these to end up in my $duplicates array, with the respective id and title together.
There's the array_unique function too, but I can't quite figure out how to use this in this scenario...

Assuming $titles[] = array( 'id' => integer, 'title' => string ); and also that id:title is a 1:1 mapping
$count = array();
foreach( $titles as $title ) {
if( !isset($count[$title['id']]) ) {
$count[$title['id']] = 1;
} else {
$count[$title['id']]++;
}
}
foreach( $titles as $title ) {
if( $count[$title['id']] > 1 ) {
$duplicates[] = $title;
}
}

if (!in_array($post_title, $titles)){
array_push( $titles, $post_title) );
}
array_push( $duplicates, $post_title) );
//end while
This way you store the original and the duplicates in the $duplicates array.
Alternatively you can use:
$titles = array_unique( $original_array );

Related

Wordpress - Only display first post title in list if multiple posts have the same title

I've written a couple of shortcodes that display the titles of posts (events) per category, however I have some posts that have the same name, because they are the same event, but have a different date. These duplicate names in my list are sure to cause confusion to visitors and don't look good, so I want to only display the first post with the same name. I can't just change the names, because I have a different list that bundles posts with the same name together for a calendar. I'm using The Events Calendar btw.
So my question is: how do i apply a filter or an if statement to display only the first of a series of posts with the same title, while not impacting the display of posts without a duplicate name?
It looks a bit like this currently:
Category
- crafting
- drawing
- origami <--
- origami <--
- origami <--
- woodworking
Origami appears thrice and I want it to only appear once.
My shortcode looks like this:
extract(
shortcode_atts(
array(
'posts_per_page' => -1,
),
$atts
)
);
$args = array(
'posts_per_page' => $posts_per_page,
);
ob_start();
$events = tribe_get_events( $args );
echo '<ul>';
foreach ($events as $event) {
$parent = $event->post_parent;
if(has_term(9,'tribe_events_cat', $event) && !$parent){
echo '<li>' . $event->post_title . '</li>';
}
}
echo '</ul>';
wp_reset_query();
$retVal = ob_get_contents();
ob_end_clean();
return $retVal;
I was thinking if it is possible to check if the previous item in the loop has the same title so I added the following to the if statement, but it didn't work sadly:
$prev = get_previous_post();
if($prev->post_title != $event->post_title){
You can push the results into a new array if they are not already there... something like:
$eventsArray = array();
foreach($events as $event){
if ( in_array($event, $eventsArray) ) {
continue;
}
$eventsArray[] = $event;
}
Other way is to store all the posted title in an array and check the condition.
// create an array to store all the titles which are displyed
$previous_posts = array();
foreach ($events as $event) {
$parent = $event->post_parent;
// add extra condition to check the title is not in previous posts array
if(has_term(9,'tribe_events_cat', $event) && !$parent && !in_array($event->post_title,$previous_posts)){
echo '<li>' . $event->post_title . '</li>';
}
// store all the titles to array
$previous_posts[] = $event->post_title;
}

How to filter custom field array through get post meta then write to CSV

I have a code snippet that I use throughout my site, it reads the product IDs from a custom field "menu_listing" and displays content (like image, title, hyperlink, etc.) in an unordered list. I use this in various places on my site (ex. https://eatgoodathome.com/order/menu).
I am trying to get that list of product names to output next to customer order info in my Export Orders to CSV plugin. Here is the code pertaining to "menu_listing".
global $post;
// Date Range Parameters
$today = date("Y-m-d");
$next = date("Y-m-d", strtotime( "$today +2 weeks"));
// Query current menu based on date
$menu_args = array(
'post_type'=>'single_menu',
'posts_per_page' => 1,
'meta_query' => array(
array(
'key' => "delivery_date",
'value' => array( $today, $next ),
'type' => 'date',
'compare' => 'BETWEEN'
),
));
// Display custom field
$menu = new WP_Query( $menu_args );
if ( $menu->have_posts() ) {
while ( $menu->have_posts() ) {
$menu->the_post();
}
// This is the custom field, content looks like this: [{"id":"9115"},{"id":"8256"},{"id":"8539"},{"id":"5586"}]
$current_menu = json_decode( stripcslashes( get_post_field( "menu_listing", $post->id ) ) );
if( $current_menu ){
foreach( $current_menu as $single_block ) {
if( $single_block->id ) {
$dishes = get_post( $single_block->id )->post_title;
}}}}
//Output CSV cells
$row = array( $dishes );
In the state shown above, it loops through all the all the products, and only displays the name for the last one. I tried using implode(), explode(), an additional foreach() — those all seem to be a step in the wrong direction, outputting a blank column. What am I missing?
It looks like you're reassigning the value of $dishes with each iteration which is why you're only seeing the name of the last item. Try doing this instead:
$dishes[] = get_post( $single_block->id )->post_title;
This way, you'll be creating a new index of the $dishes array every iteration instead of reassigning its value. Then you can just assign $row = $dishes.
SOLUTION: The code in my question looped through the array and only gave the last item in the array. My goal was to loop through each key/value pair, convert the value ("id") to title, and have each title populate a column for my csv. My solution involved scrapping the foreach statement, and requesting each array in the loop by its offset, then assigning it a column in the csv file.
//Output for CSV
$output = fopen('php://output', 'w');
if ( $menu->have_posts() ) {
while ( $menu->have_posts() ) {
$menu->the_post();
}
// This is the custom field, content looks like this: [{"id":"9115"},{"id":"8256"},{"id":"8539"},{"id":"5586"}]
$current_menu = json_decode( stripcslashes( get_post_field( "menu_listing", $post->id ) ) );
$dish1 = get_post( $current_menu[0]->id )->post_title;
$dish2 = get_post( $current_menu[1]->id )->post_title;
$dish3 = get_post( $current_menu[2]->id )->post_title;
// Validate for 4th array item, if exists
if( sizeof($current_menu) === 4 ) {
$dish4 = get_post( $current_menu[3]->id )->post_title;
} else {
$dish4 = "";
}
}
//Output CSV cells
$row = array( $dish1, $dish2, $dish3, $dish4 );
fputcsv( $output, $row );

Create associated array out of taxonomy terms

I'm trying to get associated array out of taxonomy slug and taxonomy name. I have this
foreach (get_terms('taxonomy') as $tax_term) {
$taxonomy_slug = $tax_term->slug;
$taxonomy_name = $tax_term->name;
}
The issue is, that these are just strings glued together, I don't know how to separate them :\ When I print_r them out I get:
term1term2term3term4...
What I need is a way to separate those, and then create array that will look like this:
Array(
['term_1'] => Term 1
['term_2'] => Term 2
...
)
Is this possible?
As per your inputs in comments I have tried to find out the solution. Hope this will helps you.
$terms = array();
foreach (get_terms('taxonomy') as $tax_term) {
$taxonomy_slug = $tax_term->slug;
$taxonomy_name = $tax_term->name;
$exploded = explode($taxonomy_name,$taxonomy_slug);
foreach ($exploded as $termValue) {
if (!empty($termValue)) {
$terms[$taxonomy_name."_".$termValue] = ucfirst($taxonomy_name)." ".$termValue;
}
}
}
echo "<pre>"; print_r($terms);

Gravity forms input values

I'm new in the php world and i'm trying to build something in wordpress by gravity forms.
Basicly for now I just playing around and try to create some codes I can use when I start building. My question is: I have a form 1 where I can enter a name e.g. Football,Baseball,Hockey and it get saved to my data base. Then I have another form with the id 2 where there is a drop down box, here i want those values(names) submitted in form 1 to be dynamically populated. I have been trying to create a code by finding pieces around some websites (you will properly discover I'm mixing everything together) and ended up with this:
add_filter("gform_pre_render", "test_task");
add_filter("gform_admin_pre_render", "test_task");
add_filter('gform_pre_submission_filter', 'test_task');
function test_task($entry, $form){
if($form["id"] != 2)
return $form;
$entry["1"];
$items = array();
$items[] = array("text" => "Choose Sport", "value" => "");
foreach($posts as $post)
$items[] = array("value" => $post->post_title, "text" => $post->post_title);
foreach($form["fields"] as &$field)
if($field["id"] == 2){
$field["choices"] = $items;
}
return $form;
}
Hope someone can show me how it should be done so I can learn to do it in the future.
Sincerely
Lars
I'm afraid the $entry object is not available to the gform_pre_render, gform_pre_submission_filter or gform_admin_pre_render hooks. Give the following a try.
add_filter( 'gform_pre_render', 'populate_sports_choices' );
add_filter( 'gform_pre_validation', 'populate_sports_choices' );
add_filter( 'gform_pre_submission_filter', 'populate_sports_choices' );
add_filter( 'gform_admin_pre_render', 'populate_sports_choices' );
function populate_sports_choices( $form ) {
// only run for form 2
if( $form['id'] != 2 )
return $form;
foreach ( $form['fields'] as &$field ) {
function populate_sports_choices( $form ) {
foreach ( $form['fields'] as &$field ) {
// only populate the field if it is a select and has the designated css class name
if ( $field['type'] != 'select' || strpos( $field['cssClass'], 'populate-sport' ) === false )
continue;
// get form 1 field 4 entry values
$sports = get_entry_field_values( 4, 1 );
// create the $choices array and set the placeholder choice
$choices = array( array( 'text' => 'Select a Sport', 'value' => '' ) );
// loop through each of the sports and add them to the $choices array
foreach ( $sports as $sport ) {
$choices[] = array( 'text' => $sport['value'], 'value' => $sport['value'] );
}
//replace the field choices with the contents of the $choices array
$field['choices'] = $choices;
}
return $form;
}
/**
* Allows you to retrieve an array of field values.
* Requires either the $field object or a field ID and a form ID.
*
* Example: $values = get_entry_field_values( 5, 113 );
*/
function get_entry_field_values( $field_id, $form_id ) {
global $wpdb;
if ( is_array( $field_id ) ) {
$field_id = rgget( 'id', $field_id );
}
$tablename = $wpdb->prefix . 'rg_lead_detail';
$sql = "SELECT value FROM $tablename WHERE form_id = %d AND CAST(field_number as unsigned) = %d";
return $wpdb->get_results( $wpdb->prepare( $sql, $form_id, $field_id ), ARRAY_A );
}
The above is based on examples from the following sources:
http://www.gravityhelp.com/documentation/page/Dynamically_Populating_Drop_Down_Fields
http://www.gravityhelp.com/forums/topic/drop-down-dynamic-population-from-single-line-text
I don't think you need to write any code at all. This is supported by Gravity Forms itself. In the form editor go to settings > confirmations, then choose redirect, enter the page form 2 is on and select Pass Field Data Via Query String then enter name={Name:1} or something similar depending on the name and id of the fields in Form 1. And then in Form 2, go to the field you want to populate and select advanced and dynamically prepopulate and enter what you typed to the left of the =, in this case name.

Return all values stored in var outside foreach loop

So I assume something is being overwritten but I am unsure as to how to stop this and retrieve all values outside loop. Any ideas?
foreach($gallids as $gallterm)
{
$postterms = wp_get_post_terms($gallterm, 'type', array("fields" => "slugs"));
$checkmissing = $postterms[0];
print_r($checkmissing); // Check Terms for missing images - works here.
}
print_r($checkmissing); // Check Terms for missing images - not working here
// - seems to be getting last or first val only.
First of all initialize the variable you want to use later on:
$checkmissing = array();
Then inside the foreach append the first entry of the post terms to that array:
foreach($gallids as $gallterm)
{
list($checkmissing[]) = wp_get_post_terms($gallterm, 'type', array("fields" => "slugs"));
}
See $checkmissing[], that is what effectively will prevent that you overwrite it. It will append each to the array.
Finally you can output the result after the loop:
print_r($checkmissing);
Note: You should do some additional handling if wp_get_post_terms returns an empty array:
foreach($gallids as $gallterm)
{
$terms = wp_get_post_terms($gallterm, 'type', array("fields" => "slugs"))
AND list($checkmissing[]) = $terms
;
}
I tried a few of the examples above and they didn't quite work the way I wanted. So I poked around and did a little research, here's how I got it working for me.
In my particular case I needed to grab all the category ID's for a specific post, then return that variable into the WP_Query arguments array.
First, you will need to grab the post terms
$terms = get_the_terms( $post->ID, 'category' );
Next you'll want to initialize the variable you want to use later on:
$cat_terms = array();
Next you'll declare the foreach to get each individual term ID
foreach ( $terms as $term ) {
$cat_terms[] = $term->term_id;
}
Now let's say you want to use return a comma separated list for this $cat_terms variable. We're going to use the 'join' function
$comma_separated_terms = join( ", ", $cat_terms );
Now let's say you want to use this variable to put into you WP_Query loop for say the 'category__in' parameter. We're going to use 'array_values'.
$values = array_values($cat_terms);
The nice thing about this is now we can insert this $values variable into the WP_Query arguments:
<?php global $post;
$query = new WP_Query(array(
'post_type' => 'post_type_name',
'category__in' => $values));
?>
In my particular case, the client wanted some custom post types to display in the sidebar based on the blog posts categories. So I needed to get all the blog post terms and match them up with the terms for the custom post types categories.
Final Code Looked something like this:
<?php
$terms = get_the_terms( $post->ID, 'category' );
$cat_terms = array();
foreach ( $terms as $term ) {
$cat_terms[] = $term->term_id;
}
$values = array_values($cat_terms);
?>
<h3><?php echo $title; ?></h3>
<?php global $post;
$query = new WP_Query(array(
'post_type' => 'custom_post_type',
'category__in' => $values));
if ( $query->have_posts() ) : ?>
<?php while ( $query->have_posts() ) : $query->the_post(); ?>
// Code for loop goes here
<?php endwhile; endif; ?>
<?php wp_reset_postdata(); ?>
$checkmissing = array();
foreach($gallids as $gallterm)
{
$postterms = wp_get_post_terms($gallterm, 'type', array("fields" => "slugs"));
$checkmissing[] = $postterms[0];
print_r($checkmissing); // Check Terms for missing images - works here.
}
print_r($checkmissing); // Check Terms for missing images
// will get all missing images as array
foreach($gallids as $gallterm) {
$postterms = wp_get_post_terms( $gallterm, 'type', array("fields" => "slugs") );
$checkmissing[] = $postterms[0];
}
print_r($checkmissing); //Now this will be a 2d array with all your values..
$checkmissing = array();
$i=1;
foreach($gallids as $gallterm)
{
$postterms = wp_get_post_terms($gallterm, 'type', array("fields" => "slugs"));
$checkmissing[$i] = $postterms[0];
//print_r($checkmissing); // Check Terms for missing images - works here.
$i++;
}
print_r($checkmissing);

Categories