modules[ $module->id() ] = $module; add_filter( 'plugin_action_links_' . plugin_basename( $module->plugin_file() ), function( $links ) use ( $module ) { if ( current_user_can( $module->settings_capability() ) ) { array_unshift( $links, sprintf( '%s', esc_url( $module->admin_url() ), esc_html__( 'Settings', 'patchwork-order-split' ) ) ); } return $links; } ); } /** @return Module[] */ public function modules(): array { $modules = $this->modules; uasort( $modules, function( $a, $b ) { return strcasecmp( $a->name(), $b->name() ); } ); return $modules; } public function module( string $id ): ?Module { return $this->modules[ $id ] ?? null; } /** Modules that support a shared feature, e.g. 'orders_column'. */ public function modules_supporting( string $feature ): array { return array_filter( $this->modules(), function( Module $m ) use ( $feature ) { return in_array( $feature, $m->supports(), true ); } ); } /** * Other Patchwork products, suggested on the overview when not installed. * Kept short and factual (WordPress.org guideline 11: no nagging). */ public function catalog(): array { return (array) apply_filters( 'patchwork_core_catalog', [ 'split' => [ 'name' => 'Patchwork Split', 'description' => __( 'Split WooCommerce orders and handle items you can\'t fulfil.', 'patchwork-order-split' ), 'status' => 'available' ], 'locations' => [ 'name' => 'Patchwork Locations', 'description' => __( 'Multiple stores: pickup location at checkout, store-scoped orders and staff.', 'patchwork-order-split' ), 'status' => 'soon' ], ] ); } }