>|null */ private $rows; /** * Constructor. * * @param ResultStore $store Result storage. * @param Alternatives $alternatives Alternatives lookup. */ public function __construct( ResultStore $store, Alternatives $alternatives ) { $this->store = $store; $this->alternatives = $alternatives; } /** * One row per installed plugin, most severe first. * * @return array> */ public function rows(): array { if ( null !== $this->rows ) { return $this->rows; } if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $results = $this->store->get_results(); $rows = array(); foreach ( get_plugins() as $file => $data ) { $result = $results['plugins'][ $file ] ?? array( 'status' => Status::PENDING ); $row = $result + array( 'file' => (string) $file, 'local_name' => (string) ( $data['Name'] ?? $file ), 'local_version' => (string) ( $data['Version'] ?? '' ), 'active' => is_plugin_active( (string) $file ), 'slug' => '', 'alternatives' => array(), ); $row['light'] = Status::light( (string) $row['status'] ); $row['critical'] = Status::is_critical( $row ); if ( in_array( $row['status'], array( Status::CLOSED, Status::ABANDONED ), true ) ) { $row['alternatives'] = $this->alternatives->find( (string) $row['slug'], $row['local_name'] ); } $rows[] = $row; } usort( $rows, static function ( array $a, array $b ): int { $weight = array( (int) ! $a['critical'], Status::WEIGHT[ $a['status'] ] ?? 9, strtolower( $a['local_name'] ) ) <=> array( (int) ! $b['critical'], Status::WEIGHT[ $b['status'] ] ?? 9, strtolower( $b['local_name'] ) ); return $weight; } ); $this->rows = $rows; return $rows; } /** * Rows filtered by status. * * @param string[] $statuses Statuses. * @return array> */ public function rows_with_status( array $statuses ): array { return array_values( array_filter( $this->rows(), static function ( array $row ) use ( $statuses ): bool { return in_array( $row['status'], $statuses, true ); } ) ); } /** * Critical rows (closed because of a security issue). * * @return array> */ public function critical_rows(): array { return array_values( array_filter( $this->rows(), static function ( array $row ): bool { return $row['critical']; } ) ); } /** * Number of plugins per traffic light colour. * * @param array> $rows Rows. * @return array */ public static function count_lights( array $rows ): array { $counts = array( Status::RED => 0, Status::YELLOW => 0, Status::GREEN => 0, Status::GREY => 0, ); foreach ( $rows as $row ) { ++$counts[ $row['light'] ]; } return $counts; } }