*/ protected array $locations = []; /** * CSS classes for the report container * * @var array */ protected array $classes = []; /** * Tooltip/help text * * @var string|null */ protected ?string $tooltip = null; /** * Report color (for styling) * * @var string */ protected string $color = '#EFF6FF'; /** * Minimum capability required to view * * @var string */ protected string $capability = 'read'; /** * Postbox configuration options * * @var array */ protected array $postbox_config = [ 'hide_header' => false, // Hide postbox header (title + buttons) 'hide_padding' => false, // Remove postbox padding 'custom_height' => null, // Custom height for postbox 'full_width' => false, // Make postbox full width 'no_border' => false, // Remove postbox border 'no_background' => false, // Remove postbox background ]; /** * Constructor - initializes the report */ public function __construct() { $this->init(); $this->setup_capability(); } /** * Initialize report properties. * Must be implemented by child classes. * * @return void */ abstract protected function init(): void; /** * Get report data from database or other source. * Must be implemented by child classes. * * @return array */ abstract public function get_data(): array; /** * {@inheritDoc} */ public function get_id(): string { return $this->id; } /** * {@inheritDoc} */ public function get_title(): string { return $this->title; } /** * {@inheritDoc} */ public function get_locations(): array { return $this->locations; } /** * {@inheritDoc} */ public function get_classes(): array { return $this->classes; } /** * {@inheritDoc} */ public function get_tooltip(): ?string { return $this->tooltip; } /** * Get the report color * * @return string */ public function get_color(): string { return $this->color; } /** * Get the report priority for ordering (lower number = higher priority) * * @return int Default priority is 10 */ public function get_priority(): int { return 10; } /** * Get postbox configuration * * @return array */ public function get_postbox_config(): array { return $this->postbox_config; } /** * Get specific postbox configuration option * * @param string $key Configuration key * @param mixed $default Default value if key doesn't exist * @return mixed */ public function get_postbox_option( string $key, $default = null ) { return $this->postbox_config[ $key ] ?? $default; } /** * {@inheritDoc} */ public function can_view(): bool { // Check if user is whitelisted if ( false !== strpos( ( \wp_slimstat::$settings['can_view'] ?? '' ), (string) $GLOBALS['current_user']->user_login ) ) { return current_user_can( 'read' ); } // Check capability $minimum_capability = \wp_slimstat::$settings['capability_can_view'] ?? $this->capability; return current_user_can( $minimum_capability ); } /** * Setup the required capability based on settings * * @return void */ protected function setup_capability(): void { if ( ! empty( \wp_slimstat::$settings['capability_can_view'] ) ) { $this->capability = \wp_slimstat::$settings['capability_can_view']; } } /** * {@inheritDoc} */ public function render(): void { if ( ! $this->can_view() ) { return; } $this->render_header(); $this->render_content(); $this->render_footer(); } /** * Render the report header * * @return void */ protected function render_header(): void { if ( ! is_admin() ) { return; } $header_classes = implode( ' ', $this->get_classes() ); $fixed_title = str_replace( [ '-', '_', '"', "'", ')', '(' ], '', strtolower( $this->get_title() ) ); $header_classes .= ' report-' . implode( '-', explode( ' ', esc_attr( $fixed_title ) ) ); // Refresh button $header_buttons = $this->get_header_buttons(); // Tooltip $header_tooltip = $this->get_header_tooltip(); // Widget title $widget_title = '

' . esc_html( $this->get_title() ) . $header_tooltip . '

'; $bar_color = $this->get_color(); echo "
"; echo $header_buttons; echo $widget_title; echo "
"; } /** * Render the report footer * * @return void */ protected function render_footer(): void { echo '
'; } /** * Get header buttons HTML * * @return string */ protected function get_header_buttons(): string { if ( ! is_admin() ) { return ''; } $buttons = ''; // Refresh button (only if time range is current) if ( isset( wp_slimstat_db::$filters_normalized['utime']['end'] ) && wp_slimstat_db::$filters_normalized['utime']['end'] >= date_i18n( 'U' ) - 300 ) { $buttons = ''; } // Allow third-party code to add more buttons $buttons = apply_filters( 'slimstat_report_header_buttons', $buttons, $this->get_id() ); if ( ! empty( $buttons ) ) { $buttons = '
' . $buttons . '
'; } return $buttons; } /** * Get header tooltip HTML * * @return string */ protected function get_header_tooltip(): string { $tooltip_content = $this->get_tooltip(); if ( empty( $tooltip_content ) ) { $tooltip_content = esc_html( $this->get_id() ); } else { $tooltip_content .= '

' . esc_html( $this->get_id() ); } return ' ' . $tooltip_content . ''; } /** * Get the refresh URL for this report * * @return string */ protected function get_refresh_url(): string { if ( ! class_exists( '\wp_slimstat_reports' ) ) { return '#'; } return \wp_slimstat_reports::fs_url(); } /** * {@inheritDoc} */ public function to_array(): array { return [ 'title' => $this->get_title(), 'callback' => [ $this, 'render_content' ], 'callback_args' => $this->get_callback_args(), 'classes' => $this->get_classes(), 'locations' => $this->get_locations(), 'tooltip' => $this->get_tooltip(), 'color' => $this->get_color(), 'postbox_config' => $this->get_postbox_config(), 'priority' => $this->get_priority(), ]; } /** * Render content for backward compatibility * * @return void */ public function render_content(): void { // If report implements RenderableInterface and has a renderer, use it if ( $this instanceof RenderableInterface && method_exists( $this, 'get_renderer' ) ) { $renderer = $this->get_renderer(); if ( ! empty( $renderer ) && file_exists( SLIMSTAT_DIR . '/views/reports/' . $renderer . '.php' ) ) { \SlimStat\Components\View::load( 'reports/' . $renderer, [ 'args' => $this->get_callback_args(), 'data' => $this->get_data(), ] ); return; } } // Default: Show "No content" message echo '

' . esc_html__( 'No content available for this report.', 'wp-slimstat' ) . '

'; } /** * Get callback arguments for backward compatibility * * @return array */ protected function get_callback_args(): array { return []; } }