htools-8.x-1.x-dev/modules/options_element/src/OptionsUtilities.php
modules/options_element/src/OptionsUtilities.php
<?php
/**
* @file
* Contains Drupal\options_element\OptionsUtilities
*/
namespace Drupal\options_element;
/**
* Class OptionsUtilities
* @package Drupal\options_element
*/
class OptionsUtilities {
/**
* Create a textual representation of options from an array.
*
* @param $options
* An array of options used in a select list.
* @param $key_type
* How key/value pairs should be interpreted. Available options:
* - mixed
* - numeric
* - associative
* - custom
* - none
* @return string
*/
public static function optionsToText($options, $key_type) {
$output = '';
$previous_key = false;
foreach ($options as $key => $value) {
// Convert groups.
if (is_array($value)) {
$output .= '<' . $key . '>' . "\n";
foreach ($value as $subkey => $subvalue) {
$output .= (($key_type == 'mixed' || $key_type == 'numeric' || $key_type == 'custom') ? $subkey . '|' : '') . $subvalue . "\n";
}
$previous_key = $key;
}
// Typical key|value pairs.
else {
// Exit out of any groups.
if (isset($options[$previous_key]) && is_array($options[$previous_key])) {
$output .= "<>\n";
}
// Skip empty rows.
if ($options[$key] !== '') {
if ($key_type == 'mixed' || $key_type == 'numeric' || $key_type == 'custom') {
$output .= $key . '|' . $value . "\n";
}
else {
$output .= $value . "\n";
}
}
$previous_key = $key;
}
}
return $output;
}
/**
* Create an array representation of text option values.
*
* If the Key of the option is within < >, treat as an optgroup
*
* <Group 1>
* creates an optgroup with the label "Group 1"
*
* <>
* Exits the current group, allowing items to be inserted at the root element.
* @param $text
* @param $key_type
* @param bool|FALSE $flat
* @param array $duplicates
* @return array
*/
public static function optionsFromText($text, $key_type, $flat = FALSE, &$duplicates = array()) {
$keys = array();
$items = array();
$rows = array_filter(explode("\n", trim($text)), 'strlen');
$group = FALSE;
foreach ($rows as $row) {
$row = trim($row);
$matches = array();
// Check for a simple empty row.
if (!strlen($row)) {
continue;
}
// Check if this row is a group.
elseif (!$flat && preg_match('/^\<((([^>|]*)\|)?([^>]*))\>$/', $row, $matches)) {
if ($matches[1] === '') {
$group = FALSE;
}
else {
$group = $matches[4] ? $matches[4] : '';
$keys[] = $group;
}
}
// Check if this row is a key|value pair.
elseif (($key_type == 'mixed' || $key_type == 'custom' || $key_type == 'numeric') && preg_match('/^([^|]+)\|(.*)$/', $row, $matches)) {
$key = $matches[1];
$value = $matches[2];
$keys[] = $key;
$items[] = array(
'key' => $key,
'value' => $value,
'group' => $group,
);
}
// Set this this row as a straight value.
else {
$items[] = array(
'key' => NULL,
'value' => $row,
'group' => $group,
);
}
}
// Expand the list into a nested array, assign keys and check duplicates.
$options = array();
$new_key = 1;
foreach ($items as $item) {
$int_key = (int) $item['key'] * 1;
if (is_int($int_key)) {
$new_key = max($int_key, $new_key);
}
}
foreach ($items as $item) {
// Assign a key if needed.
if ($key_type == 'none') {
$item['key'] = $new_key++;
}
elseif (!isset($item['key'])) {
while (in_array($new_key, $keys)) {
$new_key++;
}
$keys[] = $new_key;
$item['key'] = $new_key;
}
if ($item['group']) {
if (isset($options[$item['group']][$item['key']])) {
$duplicates[] = $item['key'];
}
$options[$item['group']][$item['key']] = $item['value'];
}
else {
if (isset($options[$item['key']])) {
$duplicates[] = $item['key'];
}
$options[$item['key']] = $item['value'];
}
}
return $options;
}
/**
* Recursive function for finding default value keys. Matches on keys or values.
* @param $needle
* @param $haystack
* @param $include_pattern
* @return int|string
*/
public static function optionsSearch($needle, $haystack, $include_pattern) {
if (isset($haystack[$needle])) {
return $needle;
}
elseif ($include_pattern && preg_match('/' . $include_pattern . '/', $needle)) {
return $needle;
}
foreach ($haystack as $key => $value) {
if (is_array($value)) {
return self::optionsSearch($needle, $value, $include_pattern);
}
elseif ($value == $needle) {
return $key;
}
}
}
}