Make WordPress Core

Ticket #39441: 39441.6.diff

File 39441.6.diff, 23.5 KB (added by flixos90, 8 years ago)
  • src/wp-admin/includes/template.php

     
    12451245 *
    12461246 * @global $wp_settings_fields Storage array of settings fields and info about their pages/sections
    12471247 *
    1248  * @param string   $id       Slug-name to identify the field. Used in the 'id' attribute of tags.
    1249  * @param string   $title    Formatted title of the field. Shown as the label for the field
    1250  *                           during output.
    1251  * @param callable $callback Function that fills the field with the desired form inputs. The
    1252  *                           function should echo its output.
    1253  * @param string   $page     The slug-name of the settings page on which to show the section
    1254  *                           (general, reading, writing, ...).
    1255  * @param string   $section  Optional. The slug-name of the section of the settings page
    1256  *                           in which to show the box. Default 'default'.
    1257  * @param array    $args {
     1248 * @param string          $id       Slug-name to identify the field. Used in the 'id' attribute of tags.
     1249 * @param string          $title    Formatted title of the field. Shown as the label for the field
     1250 *                                  during output.
     1251 * @param callable|string $callback Function that fills the field with the desired form inputs. The
     1252 *                                  function should echo its output. May instead be one out of 'text',
     1253 *                                  'email', 'url', 'tel', 'number', 'textarea', 'checkbox', 'select',
     1254 *                                  'radio' or 'multibox' to use a default function to render the form
     1255 *                                  input.
     1256 * @param string          $page     The slug-name of the settings page on which to show the section
     1257 *                                  (general, reading, writing, ...).
     1258 * @param string          $section  Optional. The slug-name of the section of the settings page
     1259 *                                  in which to show the box. Default 'default'.
     1260 * @param array           $args {
    12581261 *     Optional. Extra arguments used when outputting the field.
    12591262 *
    1260  *     @type string $label_for When supplied, the setting title will be wrapped
    1261  *                             in a `<label>` element, its `for` attribute populated
    1262  *                             with this value.
    1263  *     @type string $class     CSS Class to be added to the `<tr>` element when the
    1264  *                             field is output.
     1263 *     @type string          $input_id       The 'id' attribute of the input field. Default is the
     1264 *                                           value of $id.
     1265 *     @type string          $input_name     The `name` attribute of the input field. Default is the
     1266 *                                           value of $id.
     1267 *     @type string          $input_class    CSS Class to be added to the input field element when
     1268 *                                           it is output. Default empty.
     1269 *     @type string          $label_for      When supplied, the setting title will be wrapped
     1270 *                                           in a `<label>` element, its `for` attribute populated
     1271 *                                           with this value. Default is the value of $input_id.
     1272 *     @type string          $class          CSS Class to be added to the `<tr>` element when the
     1273 *                                           field is output. Default empty.
     1274 *     @type string          $description    When supplied, this description will be shown below the
     1275 *                                           input field when using a default callback function.
     1276 *     @type string          $description_id When supplied, this value will be used for the `id` attribute
     1277 *                                           of the description element. Default is the value of $input_id
     1278 *                                           suffixed with '-description'.
     1279 *     @type bool            $fieldset       Whether to wrap the control in a fieldset and use the title
     1280 *                                           as its `legend`. Default false.
     1281 *     @type callable        $value_callback Callback to retrieve the value. Default is
     1282 *                                           'get_settings_field_option', which calls get_option()
     1283 *                                            based on the $input_name argument.
     1284 *     @type string|callable $before         Can be supplied to generate additional output before the
     1285 *                                           field control. It can be either a string or a callback
     1286 *                                           to generate output. Default null.
     1287 *     @type string|callable $after          Can be supplied to generate additional output after the
     1288 *                                           field control. It can be either a string or a callback
     1289 *                                           to generate output. Default null.
    12651290 * }
    12661291 */
    12671292function add_settings_field($id, $title, $callback, $page, $section = 'default', $args = array()) {
     
    12871312                $page = 'reading';
    12881313        }
    12891314
     1315        $defaults = array(
     1316                'input_id'       => $id,
     1317                'input_name'     => $id,
     1318                'input_class'    => '',
     1319                'label_class'    => '',
     1320                'class'          => '',
     1321                'description'    => '',
     1322                'fieldset'       => false,
     1323                'value_callback' => 'get_settings_field_option',
     1324                'before'         => null,
     1325                'after'          => null,
     1326        );
     1327
     1328        switch ( $callback ) {
     1329                case 'text':
     1330                case 'email':
     1331                case 'url':
     1332                case 'tel':
     1333                        $defaults['type'] = $callback;
     1334                        $callback = 'render_settings_field_text';
     1335                        break;
     1336                case 'number':
     1337                        $defaults['min'] = null;
     1338                        $defaults['max'] = null;
     1339                        $defaults['step'] = null;
     1340                        $callback = 'render_settings_field_number';
     1341                        break;
     1342                case 'textarea':
     1343                        $defaults['rows'] = null;
     1344                        $defaults['cols'] = null;
     1345                        $callback = 'render_settings_field_textarea';
     1346                        break;
     1347                case 'checkbox':
     1348                        $args['label'] = $title;
     1349                        $args['skip_title'] = true;
     1350                        $callback = 'render_settings_field_checkbox';
     1351                        break;
     1352                case 'select':
     1353                        $defaults['choices'] = array();
     1354                        $defaults['multiple'] = false;
     1355                        $callback = 'render_settings_field_select';
     1356                        break;
     1357                case 'radio':
     1358                case 'multibox':
     1359                        $defaults['choices'] = array();
     1360                        $defaults['fieldset'] = true;
     1361                        $callback = 'render_settings_field_' . $callback;
     1362                        break;
     1363        }
     1364
     1365        $args = wp_parse_args( $args, $defaults );
     1366
     1367        if ( ! empty( $args['input_id'] ) ) {
     1368                if ( ! isset( $args['label_for'] ) ) {
     1369                        $args['label_for'] = $args['input_id'];
     1370                }
     1371                if ( ! isset( $args['description_id'] ) ) {
     1372                        $args['description_id'] = $args['input_id'] . '-description';
     1373                }
     1374        }
     1375
    12901376        $wp_settings_fields[$page][$section][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback, 'args' => $args);
    12911377}
    12921378
     
    13181404
    13191405                if ( ! isset( $wp_settings_fields ) || !isset( $wp_settings_fields[$page] ) || !isset( $wp_settings_fields[$page][$section['id']] ) )
    13201406                        continue;
    1321                 echo '<table class="form-table">';
     1407                echo '<div class="settings-fields">';
    13221408                do_settings_fields( $page, $section['id'] );
    1323                 echo '</table>';
     1409                echo '</div>';
    13241410        }
    13251411}
    13261412
     
    13451431                return;
    13461432
    13471433        foreach ( (array) $wp_settings_fields[$page][$section] as $field ) {
    1348                 $class = '';
     1434                $class = 'settings-field';
    13491435
    13501436                if ( ! empty( $field['args']['class'] ) ) {
    1351                         $class = ' class="' . esc_attr( $field['args']['class'] ) . '"';
     1437                        $class .= ' ' . $field['args']['class'];
     1438                }
     1439
     1440                echo '<div class="' . esc_attr( $class ) . '">';
     1441
     1442                echo '<div class="settings-field-title">';
     1443
     1444                $label_class = '';
     1445                if ( ! empty( $field['args']['label_class'] ) ) {
     1446                        $label_class = ' class="' . esc_attr( $field['args']['label_class'] ) . '"';
     1447                }
     1448
     1449                if ( empty( $field['args']['skip_title'] ) ) {
     1450                        if ( ! empty( $field['args']['fieldset'] ) ) {
     1451                                echo '<span' . $label_class . ' aria-hidden="true">' . $field['title'] . '</span>';
     1452                        } elseif ( ! empty( $field['args']['label_for'] ) ) {
     1453                                echo '<label for="' . esc_attr( $field['args']['label_for'] ) . '"' . $label_class . '>' . $field['title'] . '</label>';
     1454                        } else {
     1455                                echo '<span' . $label_class . '>' . $field['title'] . '</span>';
     1456                        }
     1457                }
     1458
     1459                echo '</div>';
     1460
     1461                echo '<div class="settings-field-control">';
     1462
     1463                // Duplicate arguments to not modify globals permanently.
     1464                $field_args = $field['args'];
     1465
     1466                if ( ! empty( $field_args['value_callback'] ) ) {
     1467                        $field_args['value'] = call_user_func( $field_args['value_callback'], $field_args );
     1468                }
     1469
     1470                if ( ! empty( $field_args['fieldset'] ) ) {
     1471                        echo '<fieldset>';
     1472                        if ( empty( $field_args['skip_title'] ) ) {
     1473                                echo '<legend class="screen-reader-text">' . $field['title'] . '</legend>';
     1474                        }
     1475                }
     1476
     1477                if ( $field_args['before'] ) {
     1478                        if ( is_callable( $field_args['before'] ) ) {
     1479                                call_user_func( $field_args['before'], $field_args );
     1480                        } elseif ( is_string( $field_args['before'] ) ) {
     1481                                echo $field_args['before'];
     1482                        }
     1483                }
     1484
     1485                call_user_func( $field['callback'], $field_args );
     1486
     1487                if ( $field_args['after'] ) {
     1488                        if ( is_callable( $field_args['after'] ) ) {
     1489                                call_user_func( $field_args['after'], $field_args );
     1490                        } elseif ( is_string( $field_args['after'] ) ) {
     1491                                echo $field_args['after'];
     1492                        }
     1493                }
     1494
     1495                if ( ! empty( $field_args['fieldset'] ) ) {
     1496                        echo '</fieldset>';
     1497                }
     1498
     1499                echo '</div>';
     1500                echo '</div>';
     1501        }
     1502}
     1503
     1504/**
     1505 * Renders a text input for a settings field.
     1506 *
     1507 * This function is used as a default callback when specifying 'text',
     1508 * 'email', 'url' or 'tel' for the $callback parameter in
     1509 * `add_settings_field()`.
     1510 *
     1511 * @since 4.8.0
     1512 *
     1513 * @param array $field_args Field arguments. See the documentation for the
     1514 *                          $args parameter of `add_settings_field()` for a
     1515 *                          list of default arguments.
     1516 */
     1517function render_settings_field_text( $field_args ) {
     1518        $input_attrs = array(
     1519                'type'  => ! empty( $field_args['type'] ) ? $field_args['type'] : 'text',
     1520                'id'    => ! empty( $field_args['input_id'] ) ? $field_args['input_id'] : '',
     1521                'name'  => ! empty( $field_args['input_name'] ) ? $field_args['input_name'] : '',
     1522                'class' => ! empty( $field_args['input_class'] ) ? $field_args['input_class'] : '',
     1523                'value' => ! empty( $field_args['value'] ) ? $field_args['value'] : '',
     1524        );
     1525
     1526        $description_attrs = array();
     1527
     1528        if ( ! empty( $field_args['description'] ) ) {
     1529                if ( ! empty( $field_args['description_id'] ) ) {
     1530                        $description_attrs['id'] = $field_args['description_id'];
     1531                        $input_attrs['aria-describedby'] = $field_args['description_id'];
     1532                }
     1533                $description_attrs['class'] = 'description';
     1534        }
     1535
     1536        echo '<input' . attrs( $input_attrs, false ) . ' />';
     1537
     1538        if ( ! empty( $field_args['description'] ) ) {
     1539                echo '<p' . attrs( $description_attrs, false ) . '>' . $field_args['description'] . '</p>';
     1540        }
     1541}
     1542
     1543/**
     1544 * Renders a number input for a settings field.
     1545 *
     1546 * This function is used as a default callback when specifying 'number'
     1547 * for the $callback parameter in `add_settings_field()`.
     1548 *
     1549 * @since 4.8.0
     1550 *
     1551 * @param array $field_args Field arguments. See the documentation for the
     1552 *                          $args parameter of `add_settings_field()` for a
     1553 *                          list of default arguments.
     1554 */
     1555function render_settings_field_number( $field_args ) {
     1556        $input_attrs = array(
     1557                'type'  => 'number',
     1558                'id'    => ! empty( $field_args['input_id'] ) ? $field_args['input_id'] : '',
     1559                'name'  => ! empty( $field_args['input_name'] ) ? $field_args['input_name'] : '',
     1560                'class' => ! empty( $field_args['input_class'] ) ? $field_args['input_class'] : '',
     1561                'value' => ! empty( $field_args['value'] ) ? $field_args['value'] : '',
     1562        );
     1563
     1564        foreach ( array( 'min', 'max', 'step' ) as $attr ) {
     1565                if ( isset( $field_args[ $attr ] ) ) {
     1566                        $input_attrs[ $attr ] = $field_args[ $attr ];
     1567                }
     1568        }
     1569
     1570        $description_attrs = array();
     1571
     1572        if ( ! empty( $field_args['description'] ) ) {
     1573                if ( ! empty( $field_args['description_id'] ) ) {
     1574                        $description_attrs['id'] = $field_args['description_id'];
     1575                        $input_attrs['aria-describedby'] = $field_args['description_id'];
     1576                }
     1577                $description_attrs['class'] = 'description';
     1578        }
     1579
     1580        echo '<input' . attrs( $input_attrs, false ) . ' />';
     1581
     1582        if ( ! empty( $field_args['description'] ) ) {
     1583                echo '<p' . attrs( $description_attrs, false ) . '>' . $field_args['description'] . '</p>';
     1584        }
     1585}
     1586
     1587/**
     1588 * Renders a textarea input for a settings field.
     1589 *
     1590 * This function is used as a default callback when specifying 'textarea'
     1591 * for the $callback parameter in `add_settings_field()`.
     1592 *
     1593 * @since 4.8.0
     1594 *
     1595 * @param array $field_args Field arguments. See the documentation for the
     1596 *                          $args parameter of `add_settings_field()` for a
     1597 *                          list of default arguments.
     1598 */
     1599function render_settings_field_textarea( $field_args ) {
     1600        $input_attrs = array(
     1601                'id'    => ! empty( $field_args['input_id'] ) ? $field_args['input_id'] : '',
     1602                'name'  => ! empty( $field_args['input_name'] ) ? $field_args['input_name'] : '',
     1603                'class' => ! empty( $field_args['input_class'] ) ? $field_args['input_class'] : '',
     1604        );
     1605
     1606        if ( isset( $field_args['rows'] ) ) {
     1607                $input_attrs['rows'] = $field_args['rows'];
     1608        }
     1609
     1610        if ( isset( $field_args['cols'] ) ) {
     1611                $input_attrs['cols'] = $field_args['cols'];
     1612        }
     1613
     1614        $description_attrs = array();
     1615
     1616        if ( ! empty( $field_args['description'] ) ) {
     1617                if ( ! empty( $field_args['description_id'] ) ) {
     1618                        $description_attrs['id'] = $field_args['description_id'];
     1619                        $input_attrs['aria-describedby'] = $field_args['description_id'];
     1620                }
     1621                $description_attrs['class'] = 'description';
     1622        }
     1623
     1624        $value = ! empty( $field_args['value'] ) ? $field_args['value'] : '';
     1625
     1626        echo '<textarea' . attrs( $input_attrs, false ) . '>' . esc_textarea( $value ) . '</textarea>';
     1627
     1628        if ( ! empty( $field_args['description'] ) ) {
     1629                echo '<p' . attrs( $description_attrs, false ) . '>' . $field_args['description'] . '</p>';
     1630        }
     1631}
     1632
     1633/**
     1634 * Renders a dropdown input for a settings field.
     1635 *
     1636 * This function is used as a default callback when specifying 'select'
     1637 * for the $callback parameter in `add_settings_field()`.
     1638 *
     1639 * @since 4.8.0
     1640 *
     1641 * @param array $field_args Field arguments. See the documentation for the
     1642 *                          $args parameter of `add_settings_field()` for a
     1643 *                          list of default arguments.
     1644 */
     1645function render_settings_field_select( $field_args ) {
     1646        $input_attrs = array(
     1647                'id'    => ! empty( $field_args['input_id'] ) ? $field_args['input_id'] : '',
     1648                'name'  => ! empty( $field_args['input_name'] ) ? $field_args['input_name'] : '',
     1649                'class' => ! empty( $field_args['input_class'] ) ? $field_args['input_class'] : '',
     1650        );
     1651
     1652        if ( ! empty( $field_args['multiple'] ) ) {
     1653                if ( ! empty( $input_attrs['name'] ) ) {
     1654                        $input_attrs['name'] .= '[]';
     1655                }
     1656                $input_attrs['multiple'] = 'multiple';
     1657        }
     1658
     1659        $description_attrs = array();
     1660
     1661        if ( ! empty( $field_args['description'] ) ) {
     1662                if ( ! empty( $field_args['description_id'] ) ) {
     1663                        $description_attrs['id'] = $field_args['description_id'];
     1664                        $input_attrs['aria-describedby'] = $field_args['description_id'];
     1665                }
     1666                $description_attrs['class'] = 'description';
     1667        }
     1668
     1669        $choices = ! empty( $field_args['choices'] ) ? $field_args['choices'] : array();
     1670        $current = ! empty( $field_args['value'] ) ? $field_args['value'] : '';
     1671        if ( ! empty( $field_args['multiple'] ) ) {
     1672                $current = ! empty( $current ) ? (array) $current : array();
     1673        }
     1674
     1675        echo '<select' . attrs( $input_attrs, false ) . '>';
     1676
     1677        foreach ( $choices as $value => $label ) {
     1678                $selected = '';
     1679                if ( ! empty( $field_args['multiple'] ) && in_array( $value, $current ) ) {
     1680                        $selected = ' selected="selected"';
     1681                } elseif ( empty( $field_args['multiple'] ) ) {
     1682                        $selected = selected( $current, $value, false );
     1683                }
     1684                echo '<option value="' . esc_attr( $value ) . '"' . $selected . '>' . esc_html( $label ) . '</option>';
     1685        }
     1686
     1687        echo '</select>';
     1688
     1689        if ( ! empty( $field_args['description'] ) ) {
     1690                echo '<p' . attrs( $description_attrs, false ) . '>' . $field_args['description'] . '</p>';
     1691        }
     1692}
     1693
     1694/**
     1695 * Renders a checkbox input for a settings field.
     1696 *
     1697 * This function is used as a default callback when specifying 'checkbox'
     1698 * for the $callback parameter in `add_settings_field()`.
     1699 *
     1700 * @since 4.8.0
     1701 *
     1702 * @param array $field_args Field arguments. See the documentation for the
     1703 *                          $args parameter of `add_settings_field()` for a
     1704 *                          list of default arguments.
     1705 */
     1706function render_settings_field_checkbox( $field_args ) {
     1707        $input_attrs = array(
     1708                'type'  => 'checkbox',
     1709                'id'    => ! empty( $field_args['input_id'] ) ? $field_args['input_id'] : '',
     1710                'name'  => ! empty( $field_args['input_name'] ) ? $field_args['input_name'] : '',
     1711                'class' => ! empty( $field_args['input_class'] ) ? $field_args['input_class'] : '',
     1712                'value' => '1',
     1713        );
     1714
     1715        $description_attrs = array();
     1716
     1717        if ( ! empty( $field_args['description'] ) ) {
     1718                if ( ! empty( $field_args['description_id'] ) ) {
     1719                        $description_attrs['id'] = $field_args['description_id'];
     1720                        $input_attrs['aria-describedby'] = $field_args['description_id'];
    13521721                }
     1722                $description_attrs['class'] = 'description';
     1723        }
    13531724
    1354                 echo "<tr{$class}>";
     1725        $current = ! empty( $field_args['value'] ) ? $field_args['value'] : '';
    13551726
    1356                 if ( ! empty( $field['args']['label_for'] ) ) {
    1357                         echo '<th scope="row"><label for="' . esc_attr( $field['args']['label_for'] ) . '">' . $field['title'] . '</label></th>';
     1727        echo '<input' . attrs( $input_attrs, false ) . checked( $current, true, false ) . ' />';
     1728
     1729        if ( ! empty( $field_args['label'] ) ) {
     1730                if ( ! empty( $field_args['label_for'] ) ) {
     1731                        echo ' <label for="' . esc_attr( $field_args['label_for'] ) . '" class="title-label">' . $field_args['label'] . '</label>';
    13581732                } else {
    1359                         echo '<th scope="row">' . $field['title'] . '</th>';
     1733                        echo ' <span class="title-label">' . $field_args['label'] . '</span>';
    13601734                }
     1735        }
    13611736
    1362                 echo '<td>';
    1363                 call_user_func($field['callback'], $field['args']);
    1364                 echo '</td>';
    1365                 echo '</tr>';
     1737        if ( ! empty( $field_args['description'] ) ) {
     1738                echo '<p' . attrs( $description_attrs, false ) . '>' . $field_args['description'] . '</p>';
    13661739        }
    13671740}
    13681741
    13691742/**
     1743 * Renders a radio input for a settings field.
     1744 *
     1745 * This function is used as a default callback when specifying 'radio'
     1746 * for the $callback parameter in `add_settings_field()`.
     1747 *
     1748 * @since 4.8.0
     1749 *
     1750 * @param array $field_args Field arguments. See the documentation for the
     1751 *                          $args parameter of `add_settings_field()` for a
     1752 *                          list of default arguments.
     1753 */
     1754function render_settings_field_radio( $field_args ) {
     1755        $input_attrs = array(
     1756                'type'  => 'radio',
     1757                'id'    => ! empty( $field_args['input_id'] ) ? $field_args['input_id'] : '',
     1758                'name'  => ! empty( $field_args['input_name'] ) ? $field_args['input_name'] : '',
     1759                'class' => ! empty( $field_args['input_class'] ) ? $field_args['input_class'] : '',
     1760        );
     1761
     1762        $choices = ! empty( $field_args['choices'] ) ? $field_args['choices'] : array();
     1763        $current = ! empty( $field_args['value'] ) ? $field_args['value'] : '';
     1764
     1765        $id_suffix = 0;
     1766        foreach ( $choices as $value => $label ) {
     1767                $id_suffix++;
     1768
     1769                $radio_attrs = $input_attrs;
     1770                $radio_attrs['id'] .= '-' . zeroise( $id_suffix, 2 );
     1771                $radio_attrs['value'] = $value;
     1772
     1773                echo '<span class="radio-item">';
     1774                echo '<input' . attrs( $radio_attrs, false ) . checked( $current, $value, false ) . ' />';
     1775                echo ' <label for="' . $radio_attrs['id'] . '">' . $label . '</label>';
     1776                echo '</span><br />';
     1777        }
     1778
     1779        $description_attrs = array();
     1780
     1781        if ( ! empty( $field_args['description'] ) ) {
     1782                if ( ! empty( $field_args['description_id'] ) ) {
     1783                        $description_attrs['id'] = $field_args['description_id'];
     1784                }
     1785
     1786                $description_attrs['class'] = 'description';
     1787
     1788                echo '<p' . attrs( $description_attrs, false ) . '>' . $field_args['description'] . '</p>';
     1789        }
     1790}
     1791
     1792/**
     1793 * Renders a multiple checkboxes input for a settings field.
     1794 *
     1795 * This function is used as a default callback when specifying 'multibox'
     1796 * for the $callback parameter in `add_settings_field()`.
     1797 *
     1798 * @since 4.8.0
     1799 *
     1800 * @param array $field_args Field arguments. See the documentation for the
     1801 *                          $args parameter of `add_settings_field()` for a
     1802 *                          list of default arguments.
     1803 */
     1804function render_settings_field_multibox( $field_args ) {
     1805        $input_attrs = array(
     1806                'type'  => 'checkbox',
     1807                'id'    => ! empty( $field_args['input_id'] ) ? $field_args['input_id'] : '',
     1808                'name'  => ! empty( $field_args['input_name'] ) ? $field_args['input_name'] . '[]' : '',
     1809                'class' => ! empty( $field_args['input_class'] ) ? $field_args['input_class'] : '',
     1810        );
     1811
     1812        $choices = ! empty( $field_args['choices'] ) ? $field_args['choices'] : array();
     1813        $current = ! empty( $field_args['value'] ) ? (array) $field_args['value'] : array();
     1814
     1815        $id_suffix = 0;
     1816        foreach ( $choices as $value => $label ) {
     1817                $id_suffix++;
     1818
     1819                $checkbox_attrs = $input_attrs;
     1820                $checkbox_attrs['id'] .= '-' . zeroise( $id_suffix, 2 );
     1821                $checkbox_attrs['value'] = $value;
     1822
     1823                if ( in_array( $value, $current ) ) {
     1824                        $checkbox_attrs['checked'] = 'checked';
     1825                }
     1826
     1827                echo '<span class="multibox-item">';
     1828                echo '<input' . attrs( $checkbox_attrs, false ) . ' />';
     1829                echo ' <label for="' . $checkbox_attrs['id'] . '">' . $label . '</label>';
     1830                echo '</span><br />';
     1831        }
     1832
     1833        $description_attrs = array();
     1834
     1835        if ( ! empty( $field_args['description'] ) ) {
     1836                if ( ! empty( $field_args['description_id'] ) ) {
     1837                        $description_attrs['id'] = $field_args['description_id'];
     1838                }
     1839
     1840                $description_attrs['class'] = 'description';
     1841
     1842                echo '<p' . attrs( $description_attrs, false ) . '>' . $field_args['description'] . '</p>';
     1843        }
     1844}
     1845
     1846/**
     1847 * Creates an attribute string from an array of attributes.
     1848 *
     1849 * @since 4.8.0
     1850 *
     1851 * @param array $attrs Array of attributes as $key => $value pairs.
     1852 * @param bool  $echo  Optional. Whether to echo the attribute string.
     1853 *                     Default true.
     1854 * @return string The attribute string.
     1855 */
     1856function attrs( $attrs, $echo = true ) {
     1857        $attribute_string = '';
     1858
     1859        foreach ( $attrs as $key => $value ) {
     1860                $attribute_string .= ' ' . $key . '="' . esc_attr( $value ) . '"';
     1861        }
     1862
     1863        if ( $echo ) {
     1864                echo $attribute_string;
     1865        }
     1866
     1867        return $attribute_string;
     1868}
     1869
     1870/**
     1871 * Retrieves the value for a settings field, based on the field arguments.
     1872 *
     1873 * The function will call `get_option()` based on the 'input_name' argument
     1874 * passed. It will automatically look for the correct key if an array option
     1875 * is used for the field.
     1876 *
     1877 * This is the default callback function used when registering a field with
     1878 * `add_settings_field()`.
     1879 *
     1880 * @since 4.8.0
     1881 *
     1882 * @param array $field_args Field arguments. See the documentation for the
     1883 *                          $args parameter of `add_settings_field()` for a
     1884 *                          list of default arguments.
     1885 * @return mixed The value for the settings field, or null if no value set.
     1886 */
     1887function get_settings_field_option( $field_args ) {
     1888        if ( empty( $field_args['input_name'] ) ) {
     1889                return null;
     1890        }
     1891
     1892        $keys = preg_split( '/\[/', str_replace( ']', '', $field_args['input_name'] ) );
     1893        $base = array_shift( $keys );
     1894
     1895        $value = get_option( $base, null );
     1896        while ( ! empty( $keys ) ) {
     1897                $current_key = array_shift( $keys );
     1898                if ( ! isset( $value[ $current_key ] ) ) {
     1899                        return null;
     1900                }
     1901
     1902                $value = $value[ $current_key ];
     1903        }
     1904
     1905        return $value;
     1906}
     1907
     1908/**
    13701909 * Register a settings error to be displayed to the user
    13711910 *
    13721911 * Part of the Settings API. Use this to show messages to users about settings validation