PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.2
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.2
6.2.3 6.2.2 6.2.1 6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 All 156 releases
← All changes | class/class-mainwp-system-utility.php +144 -24 6.2 → 6.2.2 View file →
@@ -30,8 +30,19 @@
30 30 */
31 31 private static $instance = null;
32 32
33 33 /**
34 + * Request-local contrast results for tag backgrounds.
35 + *
36 + * Keyed by normalized #rrggbb. Invalid colors are not stored.
37 + *
38 + * @static
39 + *
40 + * @var array
41 + */
42 + private static $tag_contrast_cache = array();
43 +
44 + /**
34 45 * Method instance()
35 46 *
36 47 * Create a public static instance.
37 48 *
@@ -754,22 +765,14 @@
754 765 $tagx = MainWP_DB_Common::instance()->get_group_by_name( $tag );
755 766 $tagc = is_object( $tagx ) && '' !== $tagx->color ? $tagx->color : '';
756 767 }
757 768
758 - if ( '' !== $tagc ) {
759 - $tag_a_style = 'style="color:#fff!important;opacity:1;"';
760 - $tag_style = 'style="background-color:' . esc_html( $tagc ) . '"';
761 - } else {
762 - $tag_a_style = '';
763 - $tag_style = '';
769 + $tag_id = '';
770 + if ( isset( $tags_ids[ $idx ] ) && ! empty( $tags_ids[ $idx ] ) ) {
771 + $tag_id = $tags_ids[ $idx ];
764 772 }
765 773
766 - if ( isset( $tags_ids[ $idx ] ) && ! empty( $tags_ids[ $idx ] ) ) {
767 - $tag_id = $tags_ids[ $idx ];
768 - $tags_labels .= '<span ' . $tag_style . ' tag_id="' . $tag_id . '" class="ui tag mini label"><a ' . $tag_a_style . ' href="' . esc_url( $href . $tag_id ) . '">' . esc_html( $tag ) . '</a></span>';
769 - } else {
770 - $tags_labels .= '<span ' . $tag_style . ' class="ui tag mini label">' . esc_html( $tag ) . '</span>';
771 - }
774 + $tags_labels .= self::get_site_tag_label( $tag, $tag_id, $href, $tagc );
772 775 }
773 776 }
774 777 }
775 778 return $tags_labels;
@@ -806,26 +809,143 @@
806 809 foreach ( $tags as $idx => $tag ) {
807 810 $tag = trim( $tag );
808 811 $tagc = $tags_colors[ $idx ];
809 812
810 - if ( '' !== $tagc ) {
811 - $tag_a_style = 'style="color:#fff!important;opacity:1;"';
812 - $tag_style = 'style="background-color:' . esc_html( $tagc ) . '"';
813 - } else {
814 - $tag_a_style = '';
815 - $tag_style = '';
813 + $tag_id = '';
814 + if ( isset( $tags_ids[ $idx ] ) && ! empty( $tags_ids[ $idx ] ) ) {
815 + $tag_id = $tags_ids[ $idx ];
816 816 }
817 817
818 - if ( isset( $tags_ids[ $idx ] ) && ! empty( $tags_ids[ $idx ] ) ) {
819 - $tag_id = $tags_ids[ $idx ];
820 - $tags_labels .= '<span ' . $tag_style . ' tag_id="' . $tag_id . '" class="ui tag mini label"><a ' . $tag_a_style . ' href="' . esc_url( $href . $tag_id ) . '">' . esc_html( $tag ) . '</a></span>';
821 - } else {
822 - $tags_labels .= '<span ' . $tag_style . ' class="ui tag mini label">' . esc_html( $tag ) . '</span>';
823 - }
818 + $tags_labels .= self::get_site_tag_label( $tag, $tag_id, $href, $tagc );
824 819 }
825 820 }
826 821 }
827 822 return $tags_labels;
823 + }
824 +
825 + /**
826 + * Method get_tag_contrast_color()
827 + *
828 + * Pick white or black text for a tag background.
829 + * White is returned when its contrast is at least 4.5:1.
830 + *
831 + * @param string $background Stored tag color.
832 + *
833 + * @return string #ffffff, #000000, or an empty string when the color is unusable.
834 + */
835 + public static function get_tag_contrast_color( $background ) {
836 + $normalized = self::normalize_tag_color( $background );
837 + if ( '' === $normalized ) {
838 + return '';
839 + }
840 +
841 + if ( isset( self::$tag_contrast_cache[ $normalized ] ) ) {
842 + return self::$tag_contrast_cache[ $normalized ];
843 + }
844 +
845 + $white_contrast = 1.05 / ( self::tag_relative_luminance( $normalized ) + 0.05 );
846 + if ( $white_contrast >= 4.5 ) {
847 + $foreground = '#ffffff';
848 + } else {
849 + $foreground = '#000000';
850 + }
851 +
852 + self::$tag_contrast_cache[ $normalized ] = $foreground;
853 + return $foreground;
854 + }
855 +
856 + /**
857 + * Method normalize_tag_color()
858 + *
859 + * Reduce a stored tag color to lowercase #rrggbb.
860 + *
861 + * @param string $background Stored tag color.
862 + *
863 + * @return string Normalized color, or an empty string when it is not 3 or 6 digit hex.
864 + */
865 + private static function normalize_tag_color( $background ) {
866 + if ( ! is_string( $background ) ) {
867 + return '';
868 + }
869 +
870 + $background = trim( $background );
871 + if ( ! preg_match( '/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/', $background ) ) {
872 + return '';
873 + }
874 +
875 + $background = strtolower( $background );
876 + if ( 4 === strlen( $background ) ) {
877 + $background = '#' . $background[1] . $background[1] . $background[2] . $background[2] . $background[3] . $background[3];
878 + }
879 +
880 + return $background;
881 + }
882 +
883 + /**
884 + * Method tag_relative_luminance()
885 + *
886 + * WCAG relative luminance for a normalized #rrggbb color.
887 + *
888 + * @param string $hex Normalized background.
889 + *
890 + * @return float Luminance between 0 and 1.
891 + */
892 + private static function tag_relative_luminance( $hex ) {
893 + $red = self::tag_channel_linear( hexdec( substr( $hex, 1, 2 ) ) / 255 );
894 + $green = self::tag_channel_linear( hexdec( substr( $hex, 3, 2 ) ) / 255 );
895 + $blue = self::tag_channel_linear( hexdec( substr( $hex, 5, 2 ) ) / 255 );
896 +
897 + return ( 0.2126 * $red ) + ( 0.7152 * $green ) + ( 0.0722 * $blue );
898 + }
899 +
900 + /**
901 + * Method tag_channel_linear()
902 + *
903 + * Convert an sRGB channel to linear light.
904 + *
905 + * @param float $channel Channel from 0 to 1.
906 + *
907 + * @return float Linear channel.
908 + */
909 + private static function tag_channel_linear( $channel ) {
910 + if ( $channel <= 0.04045 ) {
911 + return $channel / 12.92;
912 + }
913 +
914 + return pow( ( $channel + 0.055 ) / 1.055, 2.4 );
915 + }
916 +
917 + /**
918 + * Method get_site_tag_label()
919 + *
920 + * Build one tag chip for the linked and plain renderers.
921 + *
922 + * @param string $tag Tag name.
923 + * @param string $tag_id Tag id. An empty id renders a plain chip.
924 + * @param string $href Link prefix.
925 + * @param string $background Stored background color.
926 + *
927 + * @return string Chip HTML.
928 + */
929 + private static function get_site_tag_label( $tag, $tag_id, $href, $background ) {
930 + $foreground = static::get_tag_contrast_color( $background );
931 + $tag_style = '';
932 +
933 + if ( '' !== $foreground ) {
934 + $normalized = self::normalize_tag_color( $background );
935 + $tag_style = 'style="background-color:' . esc_attr( $normalized ) . ';color:' . esc_attr( $foreground ) . '"';
936 + }
937 +
938 + if ( ! empty( $tag_id ) ) {
939 + $tag_a_style = 'style="opacity:1;"';
940 + if ( '' !== $foreground ) {
941 + $tag_a_style = 'style="color:' . esc_attr( $foreground ) . '!important;opacity:1;"';
942 + }
943 +
944 + return '<span ' . $tag_style . ' tag_id="' . esc_attr( $tag_id ) . '" class="ui tag mini label"><a ' . $tag_a_style . ' href="' . esc_url( $href . $tag_id ) . '">' . esc_html( $tag ) . '</a></span>';
945 + }
946 +
947 + return '<span ' . $tag_style . ' class="ui tag mini label">' . esc_html( $tag ) . '</span>';
828 948 }
829 949
830 950 /**
831 951 * Filter client tags