Render the webbook_width dropdown.

@param array $args
5753
function renderWebbookWidthField( $args ) {
		unset( $args['label_for'], $args['class'] );
		$this->renderSelect(
			[
				'id' => 'webbook_width',
				'name' => 'pressbooks_theme_options_' . $this->getSlug(),
				'option' => 'webbook_width',
				'value' => ( isset( $this->options['webbook_width'] ) ) ? $this->options['webbook_width'] : $this->defaults['webbook_width'],
				'choices' => $args,
			]
		);
	}
1306636
function renderBodyLineHightField( $args ) {
		unset( $args['label_for'], $args['class'] );
		$this->renderField(
			[
				'id' => 'pdf_body_line_height',
				'name' => 'pressbooks_theme_options_' . $this->getSlug(),
				'option' => 'pdf_body_line_height',
				'value' => ( isset( $this->options['pdf_body_line_height'] ) ) ? $this->options['pdf_body_line_height'] : $this->defaults['pdf_body_line_height'],
				'description' => $args[0],
				'append' => $args[1],
				'type' => 'text',
				'class' => 'small-text',
			]
		);
	}
1320123
function renderRomanizePartsField( $args ) {
		unset( $args['label_for'], $args['class'] );
		$this->renderCheckbox(
			[
				'id' => 'pdf_romanize_parts',
				'name' => 'pressbooks_theme_options_' . $this->getSlug(),
				'option' => 'pdf_romanize_parts',
				'value' => getset( $this->options, 'pdf_romanize_parts' ),
				'label' => $args[0],
			]
		);
	}
901500
public function widget($args, $instance)
    {
        $this->parent_page_id = View_Utils::get_top_level_parent_id();

        // We are on a 404 or search route.
        if ($this->parent_page_id === null) {
            return;
        }

        $this->args = wp_parse_args(
            $instance,
            /**
             * Edit the default Related_Pages default arguments.
             *
             * @since  1.0.0
             *
             * @param  array $defaults {
             *     The default arguments.
             *
             *     @type string $container_start   Container start HTML. Default '<ul role="navigation">'.
             *     @type string $container_end     Container end HTML. Default '</ul>'.
             *     @type string $li_class          Classes to be applied to all <li> tags. Default ''.
             *     @type string $li_active_class   Classes to be applied to the active <li> tag. Default ''.
             *     @type string $link_class        Classes to be applied to all <a> tags. Default ''.
             *     @type string $link_active_class Classes to be applied to the active <a> tag. Default 'active'.
             *     @type string $before_link       Additional content before each <a> tag. Default ''.
             *     @type string $after_link        Additional content after each <a> tag. Default ''.
             *     @type string $before_text       Additional content before each <a> tag's content. Default ''.
             *     @type string $after_text        Additional content after each <a> tag's content. Default ''.
             *     @type bool   $show_parent       Whether to show the top level page in the output. Default true.
             * }
             * @return array
             */
            apply_filters('snap_related_pages_widget_defaults', $this->get_defaults())
        );

        // Populate $pages array.
        $this->get_pages();

        if (\count($this->pages) > 0) {
            $title = apply_filters('widget_title', $instance['title']);
     
            echo $args['before_widget'];

            if (! empty($title)) {
                echo $args['before_title'] . $title . $args['after_title'];
            }
             
            $this->render();

            echo $args['after_widget'];
        }
    }
212538
public function mainMenu(array $args = [])
    {
        $defaults = [
            'searchForm'     => false,
            'btnColor'       => 'default',
            'containerEl'    => 'div',
            'containerId'    => 'navbar-collapse-main-menu',
            'containerClass' => 'navbar-collapse-main-menu navbar-collapse collapse',
            'menuEl'         => 'ul',
            'menuId'         => 'navbar-main-menu',
            'menuClass'      => 'navbar-main-menu navbar-nav nav',
            'depth'          => 2,
            'indent'         => 2
        ];

        $args = wp_parse_args($args, $defaults);
        extract($args, EXTR_SKIP);

        $tab = '    ';
        $indent = (integer) $indent;

        $wrap = [];
        $wrap[] = PHP_EOL;
        $wrap[] = str_repeat($tab, $indent + 1);
        $wrap[] = sprintf('<%s id="%%1$s" class="%%2$s">', $menuEl);
        $wrap[] = PHP_EOL;
        $wrap[] = '%3$s';
        $wrap[] = str_repeat($tab, $indent + 1);
        $wrap[] = sprintf('</%s><!-- #%s -->', $menuEl, $menuId);

        if ($searchForm) {
            $wrap[] = $this->getNavbarSearchForm($btnColor);
        }

        $wrap[] = PHP_EOL;
        $wrap[] = str_repeat($tab, $indent);

        $output = [];
        $output[] = wp_nav_menu([
            'theme_location'  => 'main-menu',
            'container'       => $containerEl,
            'container_id'    => $containerId,
            'container_class' => $containerClass,
            'menu_id'         => $menuId,
            'menu_class'      => $menuClass,
            'items_wrap'      => implode('', $wrap),
            'depth'           => $depth,
            'echo'            => false,
            'walker'          => new NavbarWalker($indent + 2)
        ]);
        $output[] = sprintf('<!-- #%s -->', $containerId);

        return apply_filters('novusopress_view_main_menu_output', implode('', $output));
    }
825708
public function addMenu(array $args = [])
    {
        $default_args = [
            'auto_prefix'   => true,
            'page_title'    => '',
            'menu_title'    => '',
            'capability'    => '',
            'page'          => '',
            'class'         => '',
            'template_file' => '',
            'template_dir'  => '',
            'icon'          => '',
            'position'      => null,
            'meta_links'    => [],
            'tabs'          => [],
            'callback'      => null,
        ];
        $cfg = (object) array_merge($default_args, $args);

        $cfg->auto_prefix   = (bool) $cfg->auto_prefix;
        $cfg->page_title    = (string) $cfg->page_title;
        $cfg->menu_title    = (string) $cfg->menu_title;
        $cfg->capability    = (string) $cfg->capability;
        $cfg->page          = (string) $cfg->page;
        $cfg->class         = (string) $cfg->class;
        $cfg->template_file = (string) $cfg->template_file;
        $cfg->template_dir  = (string) $cfg->template_dir;
        $cfg->icon          = (string) $cfg->icon;
        $cfg->position      = (string) $cfg->position;
        $cfg->meta_links    = (array) $cfg->meta_links;
        $cfg->tabs          = (array) $cfg->tabs;

        if ($cfg->page_title && $cfg->auto_prefix // Smart auto-prefixing.
                && $cfg->page_title !== $this->App->Config->©brand['©name']) {
            $cfg->page_title = $cfg->page_title.' | '.$this->App->Config->©brand['©name'];
        } elseif (!$cfg->page_title) {
            $cfg->page_title = $this->App->Config->©brand['©name'];
        }
        if (!$cfg->menu_title) {
            $cfg->menu_title = $this->App->Config->©brand['©name'];
        }
        if (!$cfg->capability) {
            $cfg->capability = $this->App->Config->§caps['§manage'];
        }
        if ($cfg->page && $cfg->auto_prefix // Smart auto-prefixing.
                && $cfg->page[0] !== '/' && mb_stripos($cfg->page, '.php') === false) {
            $cfg->page = $this->App->Config->©brand['©slug'].'-'.$cfg->page;
        } elseif (!$cfg->page) {
            $cfg->page = $this->App->Config->©brand['©slug'];
        }
        $cfg->class .= ($cfg->class ? ' ' : '').'wrap';
        $cfg->class .= ' '.$this->App::CORE_CONTAINER_SLUG.'-menu-page-area';
        $cfg->class .= ' '.$this->App::CORE_CONTAINER_SLUG.'-menu-page-wrapper';
        $cfg->class .= ' '.$this->App->Config->©brand['©slug'].'-menu-page-wrapper';
        $cfg->class .= $cfg->page !== $this->App->Config->©brand['©slug'] ? ' '.$cfg->page.'-menu-page-wrapper' : '';

        if (!$cfg->icon) {
            $cfg->icon = 'dashicons-admin-generic';
        }
        if (!isset($cfg->position[0])) {
            $cfg->position = null; // No preference.
        }
        $cfg = $this->s::applyFilters('menu_page', $cfg, $args, $default_args);

        if (!$cfg->template_file) {
            throw $this->c::issue('Missing template file.');
        }
        $cfg->nav_tabs = $this->is($cfg->page) ? $this->buildNavTabs($cfg) : '';
        $cfg->callback = $cfg->callback ?: function () use ($cfg) {
            echo $this->c::getTemplate('s-core/admin/menu-pages/template.php')->parse(compact('cfg'));
        };
        $this->hook_names[$cfg->page] = // By slug. See: <https://developer.wordpress.org/reference/functions/add_menu_page/>
            add_menu_page($cfg->page_title, $cfg->menu_title, $cfg->capability, $cfg->page, $cfg->callback, $cfg->icon, $cfg->position);
    }
848202
function renderLanguagesField( $args ) {
		unset( $args['label_for'], $args['class'] );

		$foreign_languages = get_option( 'pressbooks_global_typography' );
		if ( ! $foreign_languages ) {
			$foreign_languages = [];
		}

		$languages = Container::get( 'GlobalTypography' )->getSupportedLanguages();

		$already_supported_languages = Container::get( 'GlobalTypography' )->getThemeSupportedLanguages();

		if ( false === $already_supported_languages ) {
			$already_supported_languages = [];
		}

		$already_supported_languages_string = '';

		$i = 1;
		$c = count( $already_supported_languages );
		foreach ( $already_supported_languages as $lang ) {
			$already_supported_languages_string .= $languages[ $lang ];
			if ( $i < $c && $i === $c - 1 ) {
				$already_supported_languages_string .= ' ' . __( 'and', 'pressbooks' ) . ' ';
			} elseif ( $i < $c ) {
				$already_supported_languages_string .= ', ';
			}
			unset( $languages[ $lang ] );
			$i++;
		}

		$html = '<label id="global_typography_label" for="global_typography"> ' . $args[0] . '</label><br /><br />';
		$html .= '<select id="global_typography" class="select2" style="width: 75%" data-placeholder="' . __( 'Select languages&hellip;', 'pressbooks' ) . '" name="pressbooks_global_typography[]" multiple>';
		foreach ( $languages as $key => $value ) {
			$selected = ( in_array( $key, $foreign_languages, true ) || in_array( $key, $already_supported_languages, true ) ) ? ' selected' : '';
			$html .= '<option value="' . $key . '" ' . $selected . '>' . $value . '</option>';
		}
		$html .= '</select>';

		if ( $already_supported_languages_string ) {
			$html .= '<br /><br />' . sprintf( __( 'This theme includes built-in support for %s.', 'pressbooks' ), $already_supported_languages_string );
		}

		echo $html;
	}
1375024
public function start($args)
    {
        parent::start($args);
        $this->_dotWidth = max($this->_columns - 11 - strlen($this->_total) * 2, 10);
        $this->write("\n");
    }
838026
function renderChapterNumbersField( $args ) {
		unset( $args['label_for'], $args['class'] );
		$this->renderCheckbox(
			[
				'id' => 'chapter_numbers',
				'name' => 'pressbooks_theme_options_' . $this->getSlug(),
				'option' => 'chapter_numbers',
				'value' => ( isset( $this->options['chapter_numbers'] ) ) ? $this->options['chapter_numbers'] : '',
				'label' => $args[0],
			]
		);
	}
1083371
function renderEbookStartPointField( $args ) {
		unset( $args['label_for'], $args['class'] );

		$options = [
			'' => '--',
		];
		$struct = \Pressbooks\Book::getBookStructure();
		foreach ( $struct['front-matter'] as $k => $v ) {
			$options[ $v['ID'] ] = $v['post_title'];
		}
		foreach ( $struct['part'] as $key => $value ) {
			foreach ( $value['chapters'] as $k => $v ) {
				$options[ $v['ID'] ] = $v['post_title'];
			}
		}
		foreach ( $struct['back-matter'] as $k => $v ) {
			$options[ $v['ID'] ] = $v['post_title'];
		}

		$this->renderSelect(
			[
				'id' => 'ebook_start_point',
				'name' => 'pressbooks_theme_options_' . $this->getSlug(),
				'option' => 'ebook_start_point',
				'value' => ( isset( $this->options['ebook_start_point'] ) ) ? $this->options['ebook_start_point'] : '',
				'choices' => $options,
				'description' => $args[0],
			]
		);
	}
20296
public function url( array $args = [] ) {
		$url = get_author_posts_url( $this->ID );
		if ( $args ) {
			$url = add_query_arg( $args, $url );
		}

		return $url;
	}
988189
public function selectRow(array $args = [])
    {
        $default_args = [
            // Required.
            'label' => '',

            // Suggested.
            'tip' => '',

            // Required.
            'name'    => '',
            'value'   => '',
            'options' => [], // Or string.
            // A string is taken as `<option>` tags.

            // Optional.
            'multiple' => false,

            // Optional.
            'placeholder' => '',
            'note'        => '',

            // Optional.
            'class' => '',
            'style' => '',
            'attrs' => '',

            // Optional.
            'if' => '',
        ];
        if (!array_key_exists('value', $args)) {
            throw $this->c::issue('Missing `value` key.');
        }
        $cfg = array_merge($default_args, $args);
        $cfg = array_intersect_key($cfg, $default_args);

        foreach ($cfg as $_key => &$_value) {
            if ($_key === 'value' && (bool) $cfg['multiple']) {
                $_value = array_map('strval', (array) $_value);
            } elseif ($_key === 'value' && is_bool($_value)) {
                $_value = (string) (int) $_value;
            } elseif ($_key === 'options' && is_array($_value)) {
                $_value = array_map('strval', $_value);
            } elseif ($_key === 'multiple') {
                $_value = (bool) $_value;
            } else { // Everything else.
                $_value = (string) $_value;
            }
        } // Unset `$_value` by reference.
        unset($_key, $_value); // Housekeeping.

        if (!$cfg['name']) {
            throw $this->c::issue('Arg `name` is required.');
        }
        if (is_array($cfg['options'])) {
            $_options       = $cfg['options'];
            $cfg['options'] = ''; // Initialize.
            $_in_optgroup   = false; // Initialize.

            foreach ($_options as $_value => $_label) {
                $_value = (string) $_value;
                $_label = (string) $_label;

                if (mb_strpos($_value, '_group:') === 0) {
                    if ($_in_optgroup) {
                        $cfg['options'] .= '</optgroup>';
                    }
                    $cfg['options'] .= '<optgroup label="'.esc_attr($_label).'">';
                    $_in_optgroup = true; // Flag as true.
                } else {
                    if (is_array($cfg['value'])) {
                        $_selected = in_array($_value, $cfg['value'], true) ? ' selected' : '';
                    } else {
                        $_selected = $_value === $cfg['value'] ? ' selected' : '';
                    }
                    $cfg['options'] .= '<option value="'.esc_attr($_value).'"'.$_selected.'>'.esc_html($_label).'</option>';
                }
            }
            $cfg['options'] .= $_in_optgroup ? '</optgroup>' : ''; // Close last group.
            // unset($_value, $_label, $_selected, $_in_optgroup, $_options); // Housekeeping.
        }
        $cfg['var_name'] = $cfg['name']; // Internal copy.
        $cfg['id']       = $this->elementId($cfg['var_name']);
        $cfg['name']     = $this->elementName($cfg['var_name'].($cfg['multiple'] ? '[]' : ''));
        $cfg['class']    = $this->c::mbTrim($cfg['class'].' '.$this->elementClass($cfg['var_name']));

        if ($cfg['multiple'] && (!$cfg['tip'] || mb_strpos($cfg['tip'], 'Ctrl key') === false)) {
            $cfg['tip'] = __('Use Ctrl key (or ⌘) to select multiple items from the list.', 'wp-sharks-core').
                            ($cfg['tip'] ? '<hr />' : '').$cfg['tip'];
        }
        $cfg['tip']  = $cfg['tip'] ? $this->s::menuPageTip($cfg['tip']) : '';
        $cfg['note'] = $cfg['note'] ? $this->s::menuPageNote($cfg['note']) : '';

        $markup = '<tr'.($cfg['if'] ? ' data-if="'.esc_attr($cfg['if']).'"' : '').'>';

        if ($cfg['label']) {
            $markup .= '<th scope="row">';
            $markup .= '<div>'; // For positioning.
            $markup .= $cfg['tip'];
            $markup .= '<label for="'.esc_attr($cfg['id']).'" title="'.esc_attr($cfg['label']).'">'.
                            $cfg['label'].
                       '</label>';
            $markup .= '</div>';
            $markup .= '</th>';
        }
        $markup .= '<td'.(!$cfg['label'] ? ' colspan="2"' : '').'>';
        $markup .= '<div>'; // For positioning.
        $markup .= '<select'.
                        ' name="'.esc_attr($cfg['name']).'" id="'.esc_attr($cfg['id']).'"'.
                        ' class="'.esc_attr($cfg['class']).'" style="'.esc_attr($cfg['style']).'"'.
                        ' placeholder="'.esc_attr($cfg['placeholder']).'" autocomplete="new-password"'.
                        ($cfg['multiple'] ? ' multiple' : '').
                        ($cfg['attrs'] ? ' '.$cfg['attrs'] : '').
                        '>'.$cfg['options'].'</select>';
        $markup .= $cfg['note'];

        if ($cfg['multiple']) { // Flag used to detect a case where nothing is selected.
            // NOTE: Browsers will not submit an empty array. If nothing selected, nothing submitted.
            // With this flag, something will always be submitted, because we're hard-coding an array element.
            $markup .= '<input type="hidden" name="'.esc_attr(mb_substr($cfg['name'], 0, -2).'[___ignore]').'" />';
        }
        $markup .= '</div>';
        $markup .= '</td>';

        $markup .= '</tr>';

        return $markup;
    }
1249988
public function pageDropDown(array $args)
    {
        $default = $args['post_type']->name;
        if (isset($this->original_slugs[$args['post_type']->name])) {
            $default = self::$originalSlugs[$args['post_type']->name];
        }

        wp_dropdown_pages(array(
            'post_status'      => array('publish', 'private'),
            'name'             => esc_attr($args['name']),
            'id'               => esc_attr($args['name'] . '_dropdown'),
            'selected'         => esc_attr($args['value']),
            'show_option_none' => sprintf(__('Default (/%s/)'), $default),
        ));

        $useTemplate = checked(get_option('page_for_' . $args['post_type']->name . '_template'), 'on', false);
        if ($useTemplate) {
            echo '<label style="margin-left: 10px;"><input type="checkbox" name="page_for_' . $args['post_type']->name . '_template" checked> ' . __('Use template from page', 'wp-page-for-post-type') . '</label>';
        } else {
            echo '<label style="margin-left: 10px;"><input type="checkbox" name="page_for_' . $args['post_type']->name . '_template"> ' . __('Use template from page', 'wp-page-for-post-type') . '</label>';
        }

        $useContent = checked(get_option('page_for_' . $args['post_type']->name . '_content'), 'on', false);
        if ($useContent) {
            echo '<label style="margin-left: 10px;"><input type="checkbox" name="page_for_' . $args['post_type']->name . '_content" checked> ' . __('Use content from page', 'wp-page-for-post-type') . '</label>';
        } else {
            echo '<label style="margin-left: 10px;"><input type="checkbox" name="page_for_' . $args['post_type']->name . '_content"> ' . __('Use content from page', 'wp-page-for-post-type') . '</label>';
        }
    }
702204
function renderMarginsField( $args ) {
		unset( $args['label_for'], $args['class'] );
		?>
		<div class="margin-diagram">
			<p class="description"><?php echo $args[0]; ?></p>
			<div class="pages">
				<div class="page left">
					<div class="margin outside"></div>
					<div class="margin top"></div>
					<div class="margin inside"></div>
					<div class="margin bottom"></div>
				</div>
				<div class="page right">
					<div class="margin inside"></div>
					<div class="margin top"></div>
					<div class="margin outside"></div>
					<div class="margin bottom"></div>
				</div>
			</div>
			<div class="legend">
				<ul>
					<li class="outside"><span class="color"></span> <?php _e( 'Outside Margin', 'pressbooks' ); ?></li>
					<li class="inside"><span class="color"></span> <?php _e( 'Inside Margin', 'pressbooks' ); ?></li>
					<li class="top"><span class="color"></span> <?php _e( 'Top Margin', 'pressbooks' ); ?></li>
					<li class="bottom"><span class="color"></span> <?php _e( 'Bottom Margin', 'pressbooks' ); ?></li>
				</ul>
			</div>
		</div>
		<p>
			<strong><?php _e( 'IMPORTANT: If you plan to use a print-on-demand service, margins under 2cm on any side can cause your file to be rejected.', 'pressbooks' ); ?></strong>
		</p>
		<?php
	}
134082
function renderPageSizeField( $args ) {
		unset( $args['label_for'], $args['class'] );
		if ( ! isset( $this->options['pdf_page_size'] ) ) {
			if ( isset( $this->options['pdf_page_width'] ) && isset( $this->options['pdf_page_height'] ) ) {
				if ( '5.5in' === $this->options['pdf_page_width'] && '8.5in' === $this->options['pdf_page_height'] ) {
					$this->options['pdf_page_size'] = 1;
				} elseif ( '6in' === $this->options['pdf_page_width'] && '9in' === $this->options['pdf_page_height'] ) {
					$this->options['pdf_page_size'] = 2;
				} elseif ( '8.5in' === $this->options['pdf_page_width'] && '11in' === $this->options['pdf_page_height'] ) {
					$this->options['pdf_page_size'] = 3;
				} elseif ( '8.5in' === $this->options['pdf_page_width'] && '9.25in' === $this->options['pdf_page_height'] ) {
					$this->options['pdf_page_size'] = 4;
				} elseif ( '5in' === $this->options['pdf_page_width'] && '7.75in' === $this->options['pdf_page_height'] ) {
					$this->options['pdf_page_size'] = 5;
				} elseif ( '4.25in' === $this->options['pdf_page_width'] && '7in' === $this->options['pdf_page_height'] ) {
					$this->options['pdf_page_size'] = 6;
				} elseif ( '21cm' === $this->options['pdf_page_width'] && '29.7cm' === $this->options['pdf_page_height'] ) {
					$this->options['pdf_page_size'] = 7;
				} elseif ( '14.8cm' === $this->options['pdf_page_width'] && '21cm' === $this->options['pdf_page_height'] ) {
					$this->options['pdf_page_size'] = 8;
				} elseif ( '5in' === $this->options['pdf_page_width'] && '8in' === $this->options['pdf_page_height'] ) {
					$this->options['pdf_page_size'] = 9;
				} else {
					$this->options['pdf_page_size'] = 10;
				}
			} else {
				$this->options['pdf_page_size'] = 1;
			}
		}

		$html = "<select name='pressbooks_theme_options_pdf[pdf_page_size]' id='pdf_page_size' >";
		foreach ( $args as $key => $val ) {
			$html .= "<option value='" . ( $key + 1 ) . "' " . selected( $key + 1, $this->options['pdf_page_size'], false ) . ">$val</option>";
		}
		$html .= '</select>';
		echo $html;
	}
1308429
public function selectOptions(array $args = []): string
    {
        // Establish args.

        $default_args = [
            // Unique.
            'allow_empty'        => true,
            'allow_arbitrary'    => true,
            'option_formatter'   => null,
            'current_post_types' => null,

            // Used by {@link all()}.
            'max'         => 1000,
            'fail_on_max' => true,

            // Used by {@link total()}.
            // Used by {@link all()}.
            'filters' => !$this->Wp->is_admin
                ? ['public' => true, 'exclude_from_search' => false]
                : ['exclude_from_search' => false],
            'include'  => [],
            'exclude'  => [],
            'no_cache' => false,
        ];
        $args = array_merge($default_args, $args);
        $args = array_intersect_key($args, $default_args);

        // Unique.
        $args['allow_empty']        = (bool) $args['allow_empty'];
        $args['allow_arbitrary']    = (bool) $args['allow_arbitrary'];
        $args['option_formatter']   = is_callable($args['option_formatter']) ? $args['option_formatter'] : null;
        $args['current_post_types'] = isset($args['current_post_types']) ? (array) $args['current_post_types'] : null;
        $args['current_post_types'] = $this->c::removeEmptys(array_map('strval', $args['current_post_types']));

        // Used by {@link all()}.
        $args['max']         = max(1, (int) $args['max']);
        $args['fail_on_max'] = (bool) $args['fail_on_max'];

        // Used by {@link total()}.
        // Used by {@link all()}.
        $args['filters']  = (array) $args['filters'];
        $args['include']  = (array) $args['include'];
        $args['exclude']  = (array) $args['exclude'];
        $args['no_cache'] = (bool) $args['no_cache'];

        // Check for nothing being available (or too many).

        if (!($post_types = $this->all($args))) {
            return ''; // None available.
        }
        // Initialize several working variables needed below.

        $options                 = ''; // Initialize.
        $available_post_types    = []; // Initialize.
        $selected_post_types     = []; // Initialize.
        $default_post_type_label = __('Posts', 'wp-sharks-core');

        // Build & return all `<option>` tags.

        if ($args['allow_empty']) { // Allow ``?
            $options = '<option value=""></option>';
        }
        foreach ($post_types as $_post_type => $_post_type_object) { // \StdClass objects.
            $available_post_types[] = $_post_type; // Record all available.

            if (isset($args['current_post_types']) && in_array($_post_type, $args['current_post_types'], true)) {
                $selected_post_types[$_post_type] = $_post_type; // Flag selected post type.
            }
            $_post_type_label         = !empty($_post_type_object->labels->name) ? $_post_type_object->labels->name : $default_post_type_label;
            $_post_type_selected_attr = isset($selected_post_types[$_post_type]) ? ' selected' : '';

            // Format `<option>` tag w/ a custom formatter?

            if ($args['option_formatter']) {
                $options .= $args['option_formatter']($_post_type, $_post_type_object, [
                        'post_type_label'         => $_post_type_label,
                        'post_type_selected_attr' => $_post_type_selected_attr,
                    ], $args); // ↑ This allows for a custom option formatter.
                    // The formatter must always return an `<option></option>` tag.

            // Else format the `<option>` tag using a default behavior.
            } else { // Both front & back-end displays are the same for post types.
                $options .= '<option value="'.esc_attr($_post_type).'"'.$_post_type_selected_attr.'>'.
                                esc_html($_post_type_label).
                            '</option>';
            }
        } // unset($_post_type, $_post_type_object, $_post_type_label, $_post_selected_attr); // Housekeeping.

        if ($args['allow_arbitrary'] && $args['current_post_types']) { // Allow arbitrary select `<option>`s?
            foreach (array_diff($args['current_post_types'], $available_post_types) as $_arbitrary_post_type) {
                $options .= '<option value="'.esc_attr($_arbitrary_post_type).'" selected>'.
                                esc_html($default_post_type_label).
                            '</option>';
            } // unset($_arbitrary_post_type); // Housekeeping.
        }
        return $options; // HTML markup.
    }
1038200
public static function debug(array $args)
    {
        $label = '<div ondblclick="this.remove()" title="Double click to remove" style="cursor:pointer; position: relative; z-index: 999999; margin-top: 10px; box-shadow: 1px 1px 5px #ccc; font-family: Arial; background-color: rgba(255, 255, 0, 0.9); border: 1px dotted orange; padding: 5px 10px">';
        $label .= '<div style="border-bottom: 1px solid #eeeeee;  padding-bottom: 5px; margin-bottom: 5px; color: #666; font-size: 12px">Debug called from file: <strong>' . self::getCallingFileName(
            ) . '</strong> at line <strong>' . self::getCallingFileLine() . '</strong></div>';

        foreach ($args as $value) {
            if (is_bool($value)) {
                if (!$value) {
                    $value = '<span style="color: blue">FALSE</span>';
                } else {
                    $value = '<span style="color: blue">TRUE</span>';
                }
            }

            if (is_null($value)) {
                $value = '<span style="color: blue">NULL</span>';
            }

            if (is_string($value)) {
                if (!$value) {
                    $value = '<span style="color: blue">(empty string))</span>';
                }
            }

            $label .= '<pre>' . print_r($value, true) . '</pre>';
        }
        $label .= '</div>';

        return $label;
    }