true, 'id' => true, 'style' => true, 'role' => true, 'title' => true, 'hidden' => true, 'aria-label' => true, 'aria-hidden' => true, 'aria-live' => true, ); $paint = array( 'fill' => true, 'stroke' => true, 'stroke-width' => true, 'stroke-linecap' => true, 'stroke-linejoin' => true, 'stroke-dasharray' => true, 'stroke-dashoffset' => true, 'transform' => true, 'class' => true, ); $allowed = array( 'div' => $common, 'span' => $common, 'p' => $common, 'strong' => $common, 'em' => $common, 'code' => $common, 'h3' => $common, 'ul' => $common, 'li' => $common, 'nav' => $common, 'a' => array_merge( $common, array( 'href' => true, 'target' => true, 'rel' => true, ) ), 'button' => array_merge( $common, array( 'type' => true, 'disabled' => true, 'data-sah-action' => true, 'data-type' => true, ) ), 'svg' => array( 'class' => true, 'width' => true, 'height' => true, 'viewbox' => true, 'xmlns' => true, 'aria-hidden' => true, 'focusable' => true, 'role' => true, ), 'defs' => array(), 'lineargradient' => array( 'id' => true, 'x1' => true, 'y1' => true, 'x2' => true, 'y2' => true, ), 'stop' => array( 'offset' => true, 'stop-color' => true, ), 'circle' => array_merge( $paint, array( 'cx' => true, 'cy' => true, 'r' => true, ) ), 'path' => array_merge( $paint, array( 'd' => true ) ), ); return $allowed; } /** * Brand icon (inline SVG recreation of the SiteAuditHub logo mark). * * @param int $size Size in px. * @param string $id Unique id suffix for gradients. * @return string */ public static function logo_icon( $size = 48, $id = 'a' ) { $id = preg_replace( '/[^a-z0-9]/', '', strtolower( $id ) ); return ''; } /** * Wordmark (text with brand gradients). * * @return string */ public static function wordmark() { return ''; } /** * Monochrome menu icon as a data URI (WordPress colours it). * * @return string */ public static function menu_icon() { $svg = ''; // WordPress only recolours menu icons supplied as base64 SVG data URIs (see add_menu_page() docs). return 'data:image/svg+xml;base64,' . base64_encode( $svg ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- Required format for admin menu icons. } /** * Severity badge. * * @param string $severity Severity. * @return string */ public static function severity( $severity ) { return '' . esc_html( Catalog::label( 'severity', $severity ) ) . ''; } /** * Classification chip. * * @param string $class Classification. * @return string */ public static function classification( $class ) { return '' . esc_html( Catalog::label( 'classification', $class ) ) . ''; } /** * Score ring (SVG). * * @param int|null $score Score. * @param int $size Size. * @param string $label Visually hidden label. * @return string */ public static function ring( $score, $size = 120, $label = '' ) { $r = 52; $circ = 2 * M_PI * $r; $known = null !== $score; $value = $known ? max( 0, min( 100, (int) $score ) ) : 0; $offset = $circ * ( 1 - $value / 100 ); $tone = ! $known ? 'none' : ( $value >= 80 ? 'good' : ( $value >= 50 ? 'fair' : 'poor' ) ); $aria = $known /* translators: 1: label, 2: score */ ? sprintf( __( '%1$s: %2$d out of 100 (SiteAuditHub estimate)', 'siteaudithub' ), $label, $value ) /* translators: %s: label */ : sprintf( __( '%s: not available yet', 'siteaudithub' ), $label ); return ''; } /** * Local date/time for a UTC DB datetime. * * @param string|null $utc DB datetime. * @return string */ public static function datetime( $utc ) { if ( ! $utc ) { return '-'; } $ts = strtotime( $utc . ' UTC' ); return $ts ? wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $ts ) : '-'; } /** * "x ago" for a UTC DB datetime. * * @param string|null $utc DB datetime. * @return string */ public static function ago( $utc ) { if ( ! $utc ) { return __( 'never', 'siteaudithub' ); } $ts = strtotime( $utc . ' UTC' ); /* translators: %s: human time difference */ return $ts ? sprintf( __( '%s ago', 'siteaudithub' ), human_time_diff( $ts ) ) : '-'; } /** * Admin page URL. * * @param string $page Page slug. * @param array $args Query args. * @return string */ public static function page_url( $page, array $args = array() ) { return add_query_arg( array_merge( array( 'page' => $page ), $args ), admin_url( 'admin.php' ) ); } /** * Item key rendered as link when it is a URL. * * @param string $key Key. * @return string */ public static function item( $key ) { if ( '' === (string) $key ) { return '' . esc_html__( 'Site-wide', 'siteaudithub' ) . ''; } if ( preg_match( '#^https?://#i', $key ) ) { $display = preg_replace( '#^https?://#i', '', $key ); return '' . esc_html( $display ) . ' ' . esc_html__( '(opens in a new tab)', 'siteaudithub' ) . ''; } if ( preg_match( '/^post:(\d+)$/', $key, $m ) ) { $link = get_edit_post_link( (int) $m[1], 'raw' ); $text = sprintf( /* translators: %d: post ID */ __( 'Post / page #%d', 'siteaudithub' ), (int) $m[1] ); return $link ? '' . esc_html( $text ) . '' : '' . esc_html( $text ) . ''; } if ( 0 === strpos( $key, 'option:' ) ) { return '' . esc_html( sprintf( /* translators: %s: option name */ __( 'Setting: %s', 'siteaudithub' ), substr( $key, 7 ) ) ) . ''; } if ( 0 === strpos( $key, 'user:' ) ) { return '' . esc_html( sprintf( /* translators: %s: username */ __( 'User: %s', 'siteaudithub' ), substr( $key, 5 ) ) ) . ''; } if ( 0 === strpos( $key, 'plugin:' ) ) { return '' . esc_html( substr( $key, 7 ) ) . ''; } return '' . esc_html( $key ) . ''; } /** * Pagination links. * * @param int $total Total rows. * @param int $page Current page. * @param int $per Per page. * @param array $args Base query args. * @return string */ public static function pagination( $total, $page, $per, array $args ) { $pages = (int) ceil( $total / max( 1, $per ) ); if ( $pages <= 1 ) { return ''; } $out = ''; } /** * Empty state block. * * @param string $title Title. * @param string $text Text. * @param string $action Optional pre-escaped action HTML. * @return string */ public static function empty_state( $title, $text, $action = '' ) { return '
' . self::logo_icon( 56, 'empty' . wp_rand( 1, 99999 ) ) . '

' . esc_html( $title ) . '

' . esc_html( $text ) . '

' . $action . '
'; } /** * Status pill for scans. * * @param string $status Status. * @return string */ public static function scan_status( $status ) { $labels = array( 'queued' => __( 'Queued', 'siteaudithub' ), 'running' => __( 'Running', 'siteaudithub' ), 'paused' => __( 'Paused', 'siteaudithub' ), 'completed' => __( 'Completed', 'siteaudithub' ), 'cancelled' => __( 'Cancelled', 'siteaudithub' ), 'failed' => __( 'Failed', 'siteaudithub' ), ); return '' . esc_html( isset( $labels[ $status ] ) ? $labels[ $status ] : $status ) . ''; } /** * Scan type label. * * @param string $type Type. * @return string */ public static function scan_type( $type ) { return 'integrity' === $type ? __( 'Malware & integrity', 'siteaudithub' ) : __( 'Site audit', 'siteaudithub' ); } }