array( __( 'Smaller images. Same originals.', 'affstackdev-image-manager' ), __( 'Prepare optimized copies, review the results, and choose how your site delivers them.', 'affstackdev-image-manager' ) ),
'library' => array( __( 'Your media, organized.', 'affstackdev-image-manager' ), __( 'Browse, organize, and edit your media from one familiar workspace.', 'affstackdev-image-manager' ) ),
'backups' => array( __( 'Backups you control.', 'affstackdev-image-manager' ), __( 'Create portable media backups and manage your connected storage.', 'affstackdev-image-manager' ) ),
'settings' => array( __( 'Set your image workflow.', 'affstackdev-image-manager' ), __( 'Choose your quality, discovery, and delivery settings.', 'affstackdev-image-manager' ) ),
'tools' => array( __( 'Image Manager tools', 'affstackdev-image-manager' ), __( 'Review system status, encoder support, and background processing.', 'affstackdev-image-manager' ) ),
'ai' => array( __( 'AI assistants', 'affstackdev-image-manager' ), __( 'Let an AI app read Image Manager and propose changes you approve.', 'affstackdev-image-manager' ) ),
);
$extra = Hooks::sections();
foreach ( $extra as $key => $tab ) {
$copy[ $key ] = array_values( $tab['heading'] );
}
$section = isset( $copy[ $section ] ) ? $section : 'optimize';
$library_url = $library_url ?: Admin::url( 'images', array( 'im_media_view' => 'library' ) );
$links = array(
'library' => array( __( 'Library', 'affstackdev-image-manager' ), $library_url ),
'optimize' => array( __( 'Optimize', 'affstackdev-image-manager' ), Admin::url( 'optimize' ) ),
'backups' => array( __( 'Backups', 'affstackdev-image-manager' ), Admin::url( 'backups' ) ),
'settings' => array( __( 'Settings', 'affstackdev-image-manager' ), Admin::url( 'settings' ) ),
'tools' => array( __( 'Tools', 'affstackdev-image-manager' ), Admin::url( 'tools' ) ),
'ai' => array( __( 'AI assistants', 'affstackdev-image-manager' ), Admin::url( 'ai' ) ),
);
foreach ( $extra as $key => $tab ) {
$links[ $key ] = array( $tab['label'], Admin::url( $key ) );
}
$plain = array_merge( array( 'ai' ), array_keys( $extra ) ); // Tabs that load as a whole page.
$action_url = 'library' === $section ? Admin::url( 'optimize' ) : $library_url;
$action_label = 'library' === $section ? __( 'Optimize images', 'affstackdev-image-manager' ) : __( 'Open library', 'affstackdev-image-manager' );
if ( $embedded ) {
// D-214 (F-SUITE-03): inside the Suite its own heading card names the product, its description and version, so
// Image Manager prints only its header button there, in its own look; on its own page it keeps the full header.
echo '';
} else {
echo '';
}
echo '
' . esc_html__( 'Sections', 'affstackdev-image-manager' ) . '' . esc_html( $links[ $section ][0] ) . '
';
if ( isset( $extra[ $section ]['intro'] ) && is_callable( $extra[ $section ]['intro'] ) ) {
call_user_func( $extra[ $section ]['intro'] );
}
}
/**
* Print the header's button: the library from the other tabs, Optimize from the library.
*
* @param string $section The tab being shown.
* @param string $url The button's address.
* @param string $label The button's text.
*/
private static function action_button( string $section, string $url, string $label ): void {
echo '' . esc_html( $label ) . '';
}
/**
* Print the tab links, the active tab marked.
*
* @param array $links Tab key => array( label, address ).
* @param string $active The active tab's key.
* @param array $plain The tabs that load as a whole page (no data-im-nav).
*/
private static function links( array $links, string $active, array $plain ): void {
foreach ( $links as $key => $link ) {
echo '' . esc_html( $link[0] ) . '';
}
}
/**
* The tags and attributes Image Manager's screens print, for wp_kses() where HTML a helper built (escaping each
* value as it went) is printed. Every element keeps its classes, IDs, data-* and ARIA attributes.
*
* @return array Tag => its allowed attributes.
*/
public static function allowed_html(): array {
static $allowed = null;
if ( null !== $allowed ) {
return $allowed;
}
$global = array_fill_keys(
array(
'class',
'id',
'title',
'role',
'hidden',
'tabindex',
'style',
'lang',
'dir',
'data-*',
'aria-atomic',
'aria-busy',
'aria-checked',
'aria-controls',
'aria-current',
'aria-describedby',
'aria-disabled',
'aria-expanded',
'aria-haspopup',
'aria-hidden',
'aria-invalid',
'aria-label',
'aria-labelledby',
'aria-live',
'aria-modal',
'aria-pressed',
'aria-relevant',
'aria-required',
'aria-selected',
'aria-sort',
'aria-valuemax',
'aria-valuemin',
'aria-valuenow',
'aria-valuetext',
),
true
);
$tags = array(
'a' => array(
'href',
'target',
'rel',
'download',
'hreflang',
'type',
),
'abbr' => array(),
'article' => array(),
'aside' => array(),
'b' => array(),
'br' => array(),
'button' => array(
'type',
'name',
'value',
'disabled',
'form',
'formaction',
'formmethod',
'formenctype',
'formtarget',
'autofocus',
),
'caption' => array(),
'code' => array(),
'dd' => array(),
'del' => array(
'datetime',
'cite',
),
'details' => array(
'open',
),
'div' => array(),
'dl' => array(),
'dt' => array(),
'em' => array(),
'fieldset' => array(
'disabled',
'form',
'name',
),
'figcaption' => array(),
'figure' => array(),
'footer' => array(),
'form' => array(
'action',
'method',
'enctype',
'target',
'novalidate',
'accept-charset',
'autocomplete',
'name',
),
'h1' => array(),
'h2' => array(),
'h3' => array(),
'h4' => array(),
'header' => array(),
'hr' => array(),
'i' => array(),
'img' => array(
'src',
'srcset',
'sizes',
'width',
'height',
'alt',
'loading',
'decoding',
'fetchpriority',
),
'input' => array(
'type',
'name',
'value',
'checked',
'disabled',
'readonly',
'required',
'min',
'max',
'step',
'maxlength',
'minlength',
'size',
'placeholder',
'pattern',
'multiple',
'accept',
'autocomplete',
'autofocus',
'form',
'list',
'inputmode',
'webkitdirectory',
'directory',
'spellcheck',
),
'ins' => array(
'datetime',
'cite',
),
'kbd' => array(),
'label' => array(
'for',
'form',
),
'legend' => array(),
'li' => array(
'value',
),
'mark' => array(),
'meter' => array(
'value',
'min',
'max',
'low',
'high',
'optimum',
),
'nav' => array(),
'ol' => array(
'start',
'reversed',
'type',
),
'optgroup' => array(
'label',
'disabled',
),
'option' => array(
'value',
'selected',
'disabled',
'label',
),
'output' => array(
'for',
'form',
'name',
),
'p' => array(),
'picture' => array(),
'pre' => array(),
'progress' => array(
'value',
'max',
),
'q' => array(
'cite',
),
's' => array(),
'section' => array(),
'select' => array(
'name',
'multiple',
'required',
'disabled',
'size',
'form',
'autocomplete',
),
'small' => array(),
'source' => array(
'src',
'srcset',
'sizes',
'type',
'media',
'width',
'height',
),
'span' => array(),
'strong' => array(),
'sub' => array(),
'summary' => array(),
'sup' => array(),
'table' => array(),
'tbody' => array(),
'td' => array(
'colspan',
'rowspan',
'headers',
),
'textarea' => array(
'name',
'rows',
'cols',
'maxlength',
'minlength',
'placeholder',
'required',
'readonly',
'disabled',
'form',
'autocomplete',
'wrap',
'spellcheck',
),
'tfoot' => array(),
'th' => array(
'colspan',
'rowspan',
'headers',
'scope',
'abbr',
),
'thead' => array(),
'time' => array(
'datetime',
),
'tr' => array(),
'u' => array(),
'ul' => array(),
);
$allowed = array();
foreach ( $tags as $tag => $own ) {
$allowed[ $tag ] = $global + array_fill_keys( $own, true );
}
return $allowed;
}
}