-1

Ok so I have tried to search around and have been working on this for 48 hours and I am stuck to the point of headache, would very much appreciate some assistance with where I am going wrong.

So for my use case I have a Wordpress site and I am trying to programmatically set default tags for a post based on a csv list that I upload into the backend and convert to an Array. I need to be able to search for a specific field when the page loads inside of the array, and then pull out a key value to feed into the wp_set_post_tags() argument. Here is what I have so far:

    $sku_file_upload = get_field( 'sku_file_upload', 'option' );
$skufileurl = $sku_file_upload['url'];
$skulist = array();
$term_name = get_field('mold_sku');
$rows = file($skufileurl);
$header = array_shift($rows); //get the header out
$header = explode(",", $header);
$final_array = array();

foreach ($rows as $row) {
    $row = explode(",", $row);
    $header[3] = str_replace(array("\r\n", "\n\r", "\n", "\r"), '', $header[3]);
    $row[3] = str_replace(array("\r\n", "\n\r", "\n", "\r"), '', $row[3]);
    $row[3] = str_replace(array("|"), ',', $row[3]);
    $final_array[] = array($header[0] => $row[0], $header[1] => $row[1], $header[2] => $row[2], $header[3] => $row[3]);
}

This works completely as expected and provides me with the following array (41 values, cut down for viewing here):

(
    [0] => Array
        (
            [Mold SKU] => 12MM-SM-SQ
            [Title] => 12mm Squares
            [Category] => Earings|Earings > Fishhooks
            [Tags] => square ,
        )

    [1] => Array
        (
            [Mold SKU] => 12MM-SQ-HOLLOW-DROP
            [Title] => Square Hollow Drop Studs
            [Category] => Earings|Earings > Studs
            [Tags] => square ,
        )

)

As a complete aside, I had considered revising the code as such to provide another way of searching, but can't figure out how to make it work but will show this version as well. Only change is to the final foreach loop above to provide value I am looking for on each post in the associative array name:

foreach ($rows as $row) {
    $row = explode(",", $row);
    $header[3] = str_replace(array("\r\n", "\n\r", "\n", "\r"), '', $header[3]);
    $row[3] = str_replace(array("\r\n", "\n\r", "\n", "\r"), '', $row[3]);
    $row[3] = str_replace(array("|"), ',', $row[3]);
    $final_array[$row[0]] = array($header[1] => $row[1], $header[2] => $row[2], $header[3] => $row[3]);
}

Which would give me the following:

Array
(
    [12MM-SM-SQ] => Array
        (
            [Title] => 12mm Squares
            [Category] => Earings|Earings > Fishhooks
            [Tags] => square ,
        )

    [12MM-SQ-HOLLOW-DROP] => Array
        (
            [Title] => Square Hollow Drop Studs
            [Category] => Earings|Earings > Studs
            [Tags] => square ,
        )
)

But I digress, just wanted to offer that in case it offers a better way of tackling the issue. So after I have this I then execute the following code on a pageload to see if things are working:

foreach ($final_array as $value){

    echo '<pre>';
    print_r($value['Mold SKU']);
    echo '</pre>';

Disappointingly, I get a ton of blank rows but this is not the case if I replace the print_r with any of the other keys ("Title" or "Category" or "Tags" in my first example obviously).

I am wondering what is going on and if it has something to do with the - in my key? I don't believe so because I took that out and still had the same results.

I could never get past this stage, but here is what I would ideally like to do:

I have a custom field in the back end of every page that is "mold_sku" and I want to have that value be what I search for in the array. So for example the SKU on the current page might be "12MM-SQ-HOLLOW-DROP" and I want to look through the $final_array that I created, find that value, and then I need to pull the "Tags" values and insert them into the wp_set_post_tags() argument. Here is how I envision it going:

  1. Loop through the array and find the sub array that contains the value I need by searching with $term_name that is defined as $term_name = get_field('mold_sku'); and feed that into $mold_sku.

  2. Use that variable to execute:

wp_set_post_tags($post_id, $tags, true);

I am not going to put all the variations of forloops I have tried in here because it wouldn't make things any more clear (at least I don't think so) and this is already clear as mud I feel.

Appreciate any help that can be provided to point me in the right direction.

EDIT

Maybe a better way to go about this is to search for the array with the information I need in a multidimensional array and have that array of values returned so I can manipulate it?

CSV for reference

Mold SKU,Title,Category,Tags
12MM-SM-SQ,12mm Squares,Earings|Earings > Fishhooks,square |
12MM-SQ-HOLLOW-DROP,Square Hollow Drop Studs,Earings|Earings > Studs,square |
12MM-SQ-O-CUTOUT,Square O Cutouts,Earings|Earings > Fishhooks,square | o | 
13MM-CIRCLES,13mm Circles,Earings|Earings > Fishhooks,circle |
14MM-SS-STUD,Studs,Earings|Earings > Studs,metal|stainless-steel |
14MM-TRI,Triangles,Earings|Earings > Fishhooks,triangle |
16MM-SS-CIRCLES,Stainless Steel Circles,Earings|Earings > Fishhooks,metal|stainless-steel | 
17MM-BBALL-DIAMONDS,17mm Baseball Diamonds,Earings|Earings > Fishhooks,baseball-diamond|
17MM-BBALL-DIAMOND-STUD,17mm Baseball Diamond Studs,Earings|Earings > Studs,baseball-diamond|
17MM-ROUND-CROSS,Rounded Cross,Earings|Earings > Fishhooks,round-cross |
18MM-DROPS,Drops,Earings|Earings > Fishhooks,drop|
18MM-STAR,Gold Stars,Earings|Earings > Fishhooks,star | 
19MM-OVAL,Ovals,Earings|Earings > Fishhooks,oval|
20MM-CIRCLES,Circles,Earings|Earings > Fishhooks,circle|
25MM-CIR-CUT,25mm Circle Cutouts,Earings|Earings > Fishhooks,circle | 
26MM-RECT-BAR,26mm Rectangle Bars,Earings|Earings > Fishhooks,rectangle-bars|
28MM-SQ-HOLLOW,Hollow Squares,Earings|Earings > Fishhooks,square | 
30MM-LEAVES,Leaves,Earings|Earings > Fishhooks,leaf|
33MM-SKIMBOARD,Skimboards,Earings|Earings > Fishhooks,skim-board | 
36MM-LONG-TRI,Long Triangles,Earings|Earings > Fishhooks,triangle | 
38MM-DIAMOND,Diamonds,Earings|Earings > Fishhooks,diamond | 
38MM-DIAMOND-CUT,Diamond Cutouts,Earings|Earings > Fishhooks,diamond |
39MM-PENTAKINDAGON,Pentakindagon,Earings|Earings > Fishhooks,pentagon | 
40MM-CIR-CUTOUT,Circle Cutouts,Earings|Earings > Fishhooks,circle|
56MM-SQ-WIN,Square Windows,Earings|Earings > Fishhooks,square | 
9MMCIR-19MMOVAL-STUD,Circle Oval Studs,Earings|Earings > Studs,oval|
CIR-CAPSULE-CUT-STUD,Circle Capsule Cutouts,Earings|Earings > Fishhooks,capsule|circle | 
CIRCLE-SQ-STUD,Circle Hollow Square Studs,Earings|Earings > Studs,square|
CIR-CUT-SQ-CUT,Circle Squares,Earings|Earings > Fishhooks,circle|square | 
CIR-SQ-CUT-STUD,Circle Square Cutout Studs,Earings|Earings > Studs,circle|square | 
HOLLOW-DROP,Hollow Drops,Earings|Earings > Fishhooks,drop|
SQ-CUT-STUD,Square Cutout Studs,Earings|Earings > Studs,square | 
SS-PRISM,Hollow Prisms,Earings|Earings > Fishhooks,metal|stainless-steel | 
TRI-STUD,Triangles,Earings|Earings > Fishhooks,triangle | 
OBTUSE-TRI,Obtuse Triangle,Earings | Earings > Fishhooks,triangle | 
CIR-SIDE-SQ-CUTOUT,Circle Side Square Cutout Studs,Earings|Earings > Studs,circle | square | 
CIR-CLOUD,Circle Cloud Studs,Earings|Earings > Studs,circle | cloud | 
LINK-CHEVRON,Link Chevrons,Earings | Earings > Fishhooks,chevron | link | 
DIAMOND-CHEVRON,Diamond Chevrons,Earings | Earings > Fishhooks,chevron | diamond | 
9MM-CIR,9mm Circles,Earings | Earings > Fishhooks,circle | 
11MM-CIR,11mm Circle Studs,Earings|Earings > Studs,circle | 
  • Does this `print_r($value['Mold SKU']);` called for the revised code? – Karim Harazin Aug 09 '20 at 22:37
  • Thanks for commenting Karim, I am not sure I am following. print_r does in the instance of all other keys provide the values, but only in the case of Mold SKU it does not. I also don't believe the code is modified after it is loaded into the initial array from the CSV, I am simply trying to loop through it. – Nick Gardner Aug 09 '20 at 22:56
  • As I see, if you used the revised code, then the `Mold SKU` will be the key of the array, so you need to change `foreach ($final_array as $value)` to `foreach ($final_array as $key => $value)` if you print the `$key` parameter then it should show the `Mold SKU` value. – Karim Harazin Aug 09 '20 at 22:59
  • https://idownvotedbecau.se/nomcve/ – SirPilan Aug 09 '20 at 23:16
  • Not sure why you downvoted Pilan, but thanks for not attempting an answer. Would have been nice to know what you thought was incomplete, I took care to provide as much detail as possible. – Nick Gardner Aug 09 '20 at 23:25
  • @Karim, thank you for that suggestion, I had achieved that before but what I am trying to do is search through the keys, and then when I find the match for the current post, extract the tags stored in that appropriate key. – Nick Gardner Aug 09 '20 at 23:26
  • @NickGardner, I think I didn't get you, it will be better if you update the question with more clear details like input and expected output that the function should return. – Karim Harazin Aug 09 '20 at 23:48
  • Your code should work fine. What do you get if you `print_r(array_keys($final_array[0]))`? Perhaps the space in `Mold SKU` isn't actually a space? – Nick Aug 10 '20 at 00:36
  • The M in MCVE stands for minimal. Use var_export to provide(relevant) data we can use, a desired output and your attemtp. I'm trying to help you buddy :) – SirPilan Aug 10 '20 at 02:12
  • While I do appreciate that, its seems a more complicated question than that and pertains to the method I am trying to employ to solve this more than just what the code is, hence the detail. For example say that I am seeking $term_name defined as $term_name = get_field('mold_sku') and for sake of argument lets just say that value is '12MM-SM-SQ' I need to be able to search the second array list for the sub associative array with the value of 12MM-SM-SQ and then extract the 'Tags' value of 'square ,' and store it in a variable for use. – Nick Gardner Aug 10 '20 at 03:31
  • So basically you just want to find out now, whether a specific _key_ exists in your array or not? https://stackoverflow.com/questions/700227/whats-quicker-and-better-to-determine-if-an-array-key-exists-in-php – CBroe Aug 10 '20 at 07:55
  • I want to find out if the key exists, and then extract additional data from that array if it does. I know that the key will exist however for this application. – Nick Gardner Aug 10 '20 at 14:52

1 Answers1

0
ini_set('auto_detect_line_endings', true);

$fp = fopen($skufileurl, 'r');
$termName = 'Example SKU';

$csvHeader = fgetcsv($fp);
while ($csvRow = fgetcsv($fp)) {
    $keyedCsvRow = array_combine($csvHeader, $csvRow);

    if ($keyedCsvRow['Mold SKU'] === $termName) {
        $keyedCsvRow['Category'] = explode('|', $keyedCsvRow['Category']);
        $keyedCsvRow['Tags'] = explode('|', $keyedCsvRow['Tags']);
        
        $finalArray = $keyedCsvRow;
        break;
    }
}

fclose($fp);

Working example.

references

  • fopen - get filepointer
  • fgetcsv - parse line as csv, return as array
  • array_combine - use first array as keys, and second as values

additional information

  • wp_set_post_tags accepts tags as array, so you can pass them as they are $finalArray['Tags']
  • Have a look at JSON (json_encode and json_decode). Its a better format for saving your sku-file. Will replace csv. Arrays in arrays will be a no-brainer.

What your question should have looked like

Title: Parse and filter data from csv-file

Hi, im trying to read Tags of a csv-file, which looks like this:

// example data of csv file (with header!)

I need to get all Tags for a given $term_name which has to match Mold SKU. This is what i tried.

// code attempt (+optionally comment where you got stuck)

Help is much appreciated :)

Happy coding :)

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
SirPilan
  • 4,649
  • 2
  • 13
  • 26
  • I appreciate you taking a look at this, but I still can't get the code you provided to work with how I am trying to apply it. The value of $finalArray is null and it doesnt seem to be evaluating each row and returning the array when it finds the value, it rather is stopping at the final row and providing that value in an array. The $keyedCsvRow value that is being passed into $finalArray contains the final row information when evaluated. – Nick Gardner Aug 11 '20 at 21:29
  • @NickGardner That means either the file is not readable(which i dont think is the case), or your csv is invalid. So again - provide the first 3 or 4 lines of your csv(with header!). Have you taken a look at my "Working example"? Is this not how the data has to look like in the end? - The script is evaluating every row until it finds the one with a matching `'Mold SKU'`. – SirPilan Aug 12 '20 at 02:26
  • Here is the CSV, I did take a look at your example and that is what I am looking for so I can manipulate the data but it makes no sense why it won't iterate over the items: – Nick Gardner Aug 12 '20 at 16:32
  • Mold SKU,Title,Category,Tags 12MM-SM-SQ,12mm Squares,Earings|Earings > Fishhooks,square | 12MM-SQ-HOLLOW-DROP,Square Hollow Drop Studs,Earings|Earings > Studs,square | 12MM-SQ-O-CUTOUT,Square O Cutouts,Earings|Earings > Fishhooks,square | o | 13MM-CIRCLES,13mm Circles,Earings|Earings > Fishhooks,circle | 14MM-SS-STUD,Studs,Earings|Earings > Studs,metal|stainless-steel | – Nick Gardner Aug 12 '20 at 16:33
  • @NickGardner Put this properly formatted to your question. - this is simply not usable: https://3v4l.org/fUGeG – SirPilan Aug 12 '20 at 16:48
  • Added to the question – Nick Gardner Aug 13 '20 at 00:20
  • @NickGardner Csv works fine: https://3v4l.org/D1d3S Maybe the line-endings are broken. In this case put `ini_set('auto_detect_line_endings', true);` anywhere before your `fopen`. – SirPilan Aug 13 '20 at 03:50
  • value of $keyedCsvRow['Mold SKU'] still = null. I appreciate the help, I had to find another solution via python to do what I was looking for. – Nick Gardner Aug 16 '20 at 16:21