Invision Power Services, Inc. * @copyright (c) Invision Power Services, Inc. * @license https://www.invisioncommunity.com/legal/standards/ * @package Invision Community * @since 5 April 2017 */ namespace IPS\Node; /* To prevent PHP errors (extending class does not exist) revealing path */ use IPS\Member; use IPS\Theme; use function defined; use function substr; if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) ) { header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' ); exit; } /** * Colorize Trait */ trait Colorize { /** * @brief Table column name that holds the feature color hex */ public static string $featureColumnName = 'feature_color'; /** * @brief Cache the calculated formatted title for this node */ protected ?string $formattedTitle = NULL; /** * @brief Cache the formatted text colour for this node */ protected ?string $featureTextColor = NULL; /** * Get HTML formatted title. Allows apps or nodes to format the title, such as adding different colours, etc * * @return string */ public function get__formattedTitle(): string { if ( $this->formattedTitle === NULL ) { $columnName = static::$featureColumnName; if ( ! $this->$columnName ) { $this->formattedTitle = $this->_title; } else { $this->formattedTitle = Theme::i()->getTemplate( 'global', 'core', 'front' )->formattedTitle( $this ); } } return $this->formattedTitle; } /** * Get the featured color for use in CSS * * @return string|null */ public function get__featureColor(): ?string { $columnName = static::$featureColumnName; return $this->$columnName; } /** * Get the featured text color for use in CSS * * @return string|null */ public function get__featureTextColor(): ?string { if ( $this->featureTextColor === NULL ) { if ( ! $this->feature_color ) { return NULL; } else { $columnName = static::$featureColumnName; $this->featureTextColor = static::featureTextColor( $this->$columnName ); } } return $this->featureTextColor; } /** * Static method to fetch the text colour based on the the contrast from the background color * * @param $featureColor * @return string */ public static function featureTextColor( $featureColor ): string { $hexColor = str_replace( '#', '', $featureColor ); $blackColor = '000000'; $textColor = '#ffffff'; /* Use luminosity contrast algorithm to determine font color */ $r1 = hexdec( substr( $hexColor, 0, 2 ) ); $g1 = hexdec( substr( $hexColor, 2, 2 ) ); $b1 = hexdec( substr( $hexColor, 4, 2 ) ); $r2 = hexdec( substr( $blackColor, 0, 2 ) ); $g2 = hexdec( substr( $blackColor, 2, 2 ) ); $b2 = hexdec( substr( $blackColor, 4, 2 ) ); $l1 = 0.2126 * pow( $r1 / 255, 2.2 ) + 0.7152 * pow( $g1 / 255, 2.2 ) + 0.0722 * pow( $b1 / 255, 2.2 ); $l2 = 0.2126 * pow( $r2 / 255, 2.2 ) + 0.7152 * pow( $g2 / 255, 2.2 ) + 0.0722 * pow( $b2 / 255, 2.2 ); $contrastRatio = 0; if ( $l1 > $l2 ) { $contrastRatio = (int) ( ( $l1 + 0.05 ) / ( $l2 + 0.05 ) ); } else { $contrastRatio = (int) ( ( $l2 + 0.05 ) / ( $l1 + 0.05 ) ); } if ( $contrastRatio > 5 ) { $textColor = '#000000'; } return $textColor; } /** * Get title from index data * * @param array $indexData Data from the search index * @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns() * @param array|NULL $containerData Basic data about the container. Only includes columns returned by container::basicDataColumns() * @param bool $escape If the title should be escaped for HTML output. If FALSE, the feature color will not be used, because that requires HTML output * @return mixed */ public static function titleFromIndexData(array $indexData, array $itemData, ?array $containerData, bool $escape = TRUE ): mixed { if ( !$escape or !isset( $containerData[ static::$databasePrefix . static::$featureColumnName ] ) ) { return parent::titleFromIndexData( $indexData, $itemData, $containerData, $escape ); } $node = $containerData; $node['title'] = Member::loggedIn()->language()->addToStack( static::$titleLangPrefix . $indexData['index_container_id'], 'NULL', array( 'escape' => true ) ); $node['text_color'] = static::featureTextColor( $node[ static::$databasePrefix . static::$featureColumnName ] ); /* Normalize */ $node['feature_color'] = $node[ static::$databasePrefix . static::$featureColumnName ]; $title = Theme::i()->getTemplate( 'global', 'core', 'front' )->formattedTitle( $node ); if ( $indexData['index_club_id'] and isset( $containerData['_club'] ) ) { return Member::loggedIn()->language()->addToStack( 'club_container_title', FALSE, array( 'sprintf' => array( $containerData['_club']['name'] ), 'htmlsprintf' => array( $title ) ) ); } else { return $title; } } }