/**
  * Returns the items in the first array that aren't in the second array.  Arrays
  * are recursively compared.  If a value in the array is set by a String key, then
  * that same key is checked in array2, otherwise, the existance of the value
  * in array2 is checked.
  * @param array $array1
  * @param array $array2
  * @return array
  */
 function array_diff_semi_assoc_recursive($array1, $array2)
 {
     $difference = array();
     foreach ($array1 as $key => $value) {
         if (is_array($value)) {
             if (!isset($array2[$key])) {
                 $difference[$key] = $value;
             } elseif (!is_array($array2[$key])) {
                 $new_diff = array_diff_semi_assoc_recursive($value, (array) $array2[$key]);
                 if (!empty($new_diff)) {
                     $difference[$key] = $new_diff;
                 }
             } else {
                 $new_diff = array_diff_semi_assoc_recursive($value, $array2[$key]);
                 if (!empty($new_diff)) {
                     $difference[$key] = $new_diff;
                 }
             }
         } else {
             if (is_string($key) && (!array_key_exists($key, $array2) || $array2[$key] != $value)) {
                 if (!(isset($array2[$key]) && is_array($array2[$key]) && in_array($value, $array2[$key]))) {
                     $difference[$key] = $value;
                 }
             } elseif (is_int($key) && !in_array($value, $array2)) {
                 $difference[] = $value;
             }
         }
     }
     return $difference;
 }
 public function itemHTML($item, $classes)
 {
     //set empty values to false so they will be removed from the built querystring
     $item->value = array_map(function ($value) {
         if (empty($value)) {
             $value = false;
         }
         return $value;
     }, $item->value);
     if ($item->selected) {
         $qs = http_build_query(array_diff_semi_assoc_recursive($this->form->getStateVars(), $item->value));
         $opt_url = $this->form->getSearchBaseURL() . (strlen($qs) ? '?' . $qs : '');
     } else {
         $qs = http_build_query(array_merge_recursive($this->form->getStateVars(), $item->value));
         $opt_url = $this->form->getSearchBaseURL() . (strlen($qs) ? '?' . $qs : '');
     }
     return sprintf('<li class="%s"><a href="%s">%s</a></li>', implode(' ', $classes), esc_url($opt_url), esc_html($item->label));
 }
 /**
  * Returns an array of selectable filter items
  * @param Lift_WP_Query $lift_query
  * @return array
  */
 protected function getControlItems($lift_query)
 {
     $facets = $lift_query->get_facets();
     if (empty($facets[$this->field->getName()])) {
         return array();
     }
     $my_facets = $facets[$this->field->getName()];
     $items = array();
     $selectedFound = false;
     $current_request = $this->field->bqToRequest($this->field->wpToBooleanQuery($lift_query->wp_query->query_vars));
     //$current_request = array_map( 'arrayify', $current_request );
     foreach ($my_facets as $bq_value => $count) {
         $facet_request_vars = $this->field->bqToRequest($this->field->getName() . ':' . $bq_value);
         $facet_wp_vars = $this->field->requestToWP($facet_request_vars);
         //determine if this item is selected by comparing the relative request vars to this query
         //we're assuming that these don't go further than 1 level deep
         $selected = 0 === count(array_diff_semi_assoc_recursive($facet_request_vars, $current_request));
         if ($selected) {
             $selectedFound = true;
         }
         $label = $this->field->wpToLabel($facet_wp_vars);
         if ($count) {
             $label = sprintf('%1$s (%2$d)', $label, $count);
         }
         $item = (object) array('selected' => $selected, 'value' => $facet_request_vars, 'label' => $label);
         $items[] = $item;
     }
     if (!$selectedFound) {
         $selectedBq = $this->field->wpToBooleanQuery($lift_query->wp_query->query_vars);
         if ($selectedBq) {
             $items[] = (object) array('selected' => true, 'value' => $this->field->bqToRequest($selectedBq), 'label' => sprintf('%1$s (%2$d)', $this->field->wpToLabel($lift_query->wp_query->query_vars), $lift_query->wp_query->found_posts));
         }
     }
     return $items;
 }