isUserAdmin() ) { return false; } if ( self::isProductType( $dataStore, 'imunify360' ) ) { return false; } $scanData = $dataStore->getScanData(); if ( ! $scanData ) { return false; } $license = $scanData->getLicense(); if ( ! $license ) { return false; } if ( ! isset( $license['user_count'] ) || ! is_numeric( $license['user_count'] ) ) { return false; } return ( 1 === $license['user_count'] ); } /** * Checks if the product type matches the given product type. * * @param DataStore $dataStore Data store instance containing scan data. * @param string $productType Product type to check against, e.g., 'imunify360', 'imunifyav'. * * @return bool True if the product type matches, false otherwise. * * @since 2.0.0 */ public static function isProductType( $dataStore, $productType ) { if ( ! $dataStore->isDataAvailable() ) { return false; } $scanData = $dataStore->getScanData(); if ( ! $scanData ) { return false; } $license = $scanData->getLicense(); if ( ! $license ) { return false; } return isset( $license['license_type'] ) && strtolower( $license['license_type'] ) === $productType; } /** * Whether the licence is positively known to sit outside the ImunifyAV * family. * * Unlike {@see isImunifyAvFamily()} this fails closed: missing scan data, * an unreadable file or a licence with no type all answer false, because * "we cannot tell" is not "Imunify360". Callers gating an action that * changes a visitor's browser must not take it on an unknown licence. * * @param DataStore $dataStore Data store instance containing scan data. * * @return bool */ public static function isKnownNonAvLicense( $dataStore ) { if ( ! $dataStore || ! $dataStore->isDataAvailable() ) { return false; } $scanData = $dataStore->getScanData(); if ( ! $scanData ) { return false; } $license = $scanData->getLicense(); if ( ! $license || ! isset( $license['license_type'] ) ) { return false; } // An edition has to be named before it can be ruled out. isset() is true // for '', and the AV-family test answers false for anything that is not // an AV string -- so negating it alone would read an unnamed edition as // "not AV, therefore Imunify360" and enforce on it. $licenseType = $license['license_type']; if ( ! is_string( $licenseType ) || '' === trim( $licenseType ) ) { return false; } return ! Edition::isImunifyAvFamily( $licenseType ); } /** * Whether the licensed edition belongs to the ImunifyAV family * (ImunifyAV or ImunifyAV+). Unlike {@see isProductType()} with an exact * 'imunifyav', this also matches the agent's 'imunifyAVPlus' edition, so an * AV+ customer — who likewise has no WAF or bot blocking — is treated like * AV rather than mistaken for Imunify360. The edition string is matched by * {@see Edition::isImunifyAvFamily()}, shared with the bot hot path. * * @param DataStore $dataStore Data store instance containing scan data. * * @return bool */ public static function isImunifyAvFamily( $dataStore ) { if ( ! $dataStore->isDataAvailable() ) { return false; } $scanData = $dataStore->getScanData(); if ( ! $scanData ) { return false; } $license = $scanData->getLicense(); if ( ! $license || ! isset( $license['license_type'] ) ) { return false; } return Edition::isImunifyAvFamily( $license['license_type'] ); } }