1

I am reading about how this is done, but all this nesting has gotten me a bit befuddled...

Here is my current code:

function if_exists($a){
        if(isset($a) && !empty($a)){
            return $a;
        } else {
            return "";
        }
    }

$my_array = array(
    array(
        "@context" => "https://schema.org",
        "@type" => "WebSite",
        "@id" => get_site_url()."#website",
        "name:" => ssd_fallback($myvar['name'],get_bloginfo('name')),
        "headline" => get_bloginfo('description'),
        "description" => $myvar['description'],
        "url" => get_site_url()
    ),
    array(
        "@context" => "https://schema.org",
        "@type" => $myvar['subtype'],
        "@id" => $myvar['org_type'],
        "url" => get_site_url(),
        "name" => get_bloginfo('name'),
        "logo" => $myvar['logo-url'],
        "image" => $myvar['image-url'],
        "description" => $myvar['description'],
        "address" => array(
            "@type" => "PostalAddress",
            "streetAddress" => $myvar['address-street'],
            "addressLocality" => $myvar['address-locality'],
            "addressRegion" => $myvar['address-region'],
            "postalCode" => $myvar['postal-code']
            ),
        "telephone" => $myvar['phone'],
        "email" => $myvar['email'],
        "openingHours" => [$opening_hours],
        "priceRange" => $myvar['price-range'],
        "areaServed" => array(
            array(
                "@type" => "GeoCircle",
                "geoMidpoint" => array(
                    "@type" => "GeoCoordinates",
                    "latitude" => $myvar['geo-lat'],
                    "longitude" => $myvar['geo-lat']
                    ),
                "geoRadius" => $myvar['geo-radius']
                )
        ),
        "sameAs" => array(
            if_exists($myvar['same-as-1']),
            if_exists($myvar['same-as-2']),
            if_exists($myvar['same-as-3']),
            if_exists($myvar['same-as-4']),
            if_exists($myvar['same-as-5']),
        ),
        "hasMap" => $myvar['has-map-url'],
        "geo" => array(
            "@type" => "GeoCoordinates",
            "latitude" => $myvar['geo-lat'],
            "longitude" => $myvar['geo-long']
        ),
        "aggregateRating" => array(
            "@type" => "AggregateRating",
            "ratingValue" => ssd_fallback($gp_avg_star_rating,$myvar['star-rating-manual']),
            "reviewCount" => ssd_fallback($gp_total_reviews,$myvar['nbr-reviews-manual'])
            )
    )
);

$my_json = json_encode($my_array,JSON_PRETTY_PRINT);

echo $my_json;

Looking at "sameAs" - you can see I'm using my function if_exists.

However when using this I still get empty strings if there is no value (as expected)

Eg JSON Results:

"sameAs": [
            "https://www.facebook.com/myco/",
            "",
            "",
            "https://www.linkedin.com/company/myco/",
            ""
        ],

Whereas I would like the output to look like this:

"sameAs": [
            "https://www.facebook.com/myco/",
            "https://www.linkedin.com/company/myco/"
        ],

Through reading I have tried array_filter but this didn't work (even if I change if_exists function to return null); upon reading further it looks like because I have a multidimensional array) on my hands.

I found a regex solution which seemed attractive over at strip null values of json object (see Jim S's answer) but this didn't do anything for me. However maybe it just needs a tweak?

Some other options I have picked up from my reading so far (beyond my current grasp to implement):

A) Specifically "targeting" the element eg by using the "path" (ie, child items in "sameAs" element), eg using unset() as per Deleting an element from an array in PHP (seems there is more than one way to remove the key actually).

B) Some kind of function or loop, which is beyond my grasp of PHP at this point.

C) Or possibly a combination of the above. ☺️

Other thoughts:

  • Would writing the array differently help to make this easier?
  • And/or is there a more direct way to reference a key without having to drill down through each level of the nesting?
  • Is it possible that a text editor or other tool could help me get the path for these array elements (regarding option A)?
Drewdavid
  • 3,071
  • 7
  • 29
  • 53
  • 2
    Side note: no need to check `isset` when using `!empty`, that will already check if the variable is set. – El_Vanja May 25 '21 at 20:37

1 Answers1

1

Rather than cleaning up the array after you define it, just filter in your array definition with array_filter to remove empties. If you want an array definition in JSON with no index numbers then use array_values:

    "sameAs" => array_values(array_filter(array(
        $myvar['same-as-1'],
        $myvar['same-as-2'],
        $myvar['same-as-3'],
        $myvar['same-as-4'],
        $myvar['same-as-5'])
    )),

Or if there are only the 5 values in $myvar or you want to use all that are there, it's simpler:

    "sameAs" => array_values(array_filter($myvar)),

Keep in mind that this will filter out empty string "", null, false and 0 integer or string.

AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
  • Wow that's cool - so you can put it right in the array itself - I didn't realize that. However this does change the output to add what look like index numbers as new keys, where there were no keys before - eg `"sameAs": { "0": "https://www.facebook.com/myco/", "3": "https://www.linkedin.com/company/myco/" },`. I'm not sure if that is still valid for schema.org structured data...? Is there any way to suppress those new keys from being inserted? – Drewdavid May 25 '21 at 20:17
  • Edited... If it matters, `array_values` will reindex so that there won't be indexes in the JSON. – AbraCadaver May 25 '21 at 20:21
  • I think it might - didn't know about `array_values`. Thank you that does work exactly as needed... and as a bonus I could remove my redundant `if_exists` function! – Drewdavid May 25 '21 at 20:24