true, 'with_header_date_control' => true, ); /** * Whether the section's data only reaches WordPress.com through the analytics * full sync, so its numbers are incomplete until that sync has finished once. * * @since 0.4.0 * @var bool */ public $requires_sync = false; /** * Availability flag or callback. * * @var bool|callable */ private $is_available = true; /** * Default layout array or callback. * * @var array|callable */ private $default_layout = array(); /** * Constructor. * * @param string $dashboard_name Dashboard identifier. * @param string $id Section identifier. * @param array $args Optional. Section arguments. */ public function __construct( $dashboard_name, $id, $args = array() ) { $this->dashboard_name = $dashboard_name; $this->id = $id; $this->slug = self::derive_slug( $id ); $this->label = $id; $this->set_props( $args ); } /** * Derives the URL-facing slug from a namespaced section identifier. * * @param string $id Section identifier, e.g. `analytics/traffic`. * @return string The segment after the namespace, e.g. `traffic`. */ private static function derive_slug( $id ) { $separator = strpos( (string) $id, '/' ); return false === $separator ? (string) $id : substr( $id, $separator + 1 ); } /** * Returns whether this section should be exposed. * * @return bool */ public function is_available() { if ( is_callable( $this->is_available ) ) { return (bool) call_user_func( $this->is_available, $this ); } return (bool) $this->is_available; } /** * Returns the section's default widget layout, run through the default-layout filter. * * @return array Array of widget instances. */ public function get_default_layout() { $layout = is_callable( $this->default_layout ) ? call_user_func( $this->default_layout, $this ) : $this->default_layout; $layout = is_array( $layout ) ? array_values( $layout ) : array(); /** * Filters a dashboard section's default widget layout. * * Each entry matches the dashboard's widget instance shape: `uuid`, `type`, optional * `attributes`, optional `placement`. Runs for every section, so a callback adding an * instance to one switches on `$section_id`. * * @since 0.8.0 Runs from the section, with its declared layout and its * namespaced id; it received an empty array and any alias before. * * @param array $layout The section's declared default widget instances. * @param string $section_id Namespaced section identifier, e.g. `analytics/traffic`. * @param Dashboard_Section $section The section. */ $layout = apply_filters( DASHBOARD_DEFAULT_LAYOUT_FILTER, $layout, $this->id, $this ); return is_array( $layout ) ? array_values( $layout ) : array(); } /** * Returns the public REST representation. * * @return array */ public function to_array() { return array( 'id' => $this->id, 'slug' => $this->slug, 'label' => $this->label, 'title' => $this->title, 'order' => (int) $this->order, 'date_filter' => $this->date_filter, 'date_filter_options' => $this->date_filter_options, 'requires_sync' => $this->requires_sync, 'default_layout' => $this->get_default_layout(), ); } /** * Hydrates section properties from the args array. * * @param array $args Section arguments. * @return void */ private function set_props( $args ) { if ( ! is_array( $args ) ) { return; } if ( isset( $args['label'] ) ) { $this->label = (string) $args['label']; } // An empty string is a registrant saying "none", not a heading: kept as-is it // would defeat the label fallback and render an `