focus = new FocusRepository(); $this->policy = new ApplyPolicy( $this->focus ); } /** * De singleton. Bij de eerste aanroep moet het pluginbestand meegegeven worden. * * @param string|null $file Pad naar het hoofdbestand. * @return Plugin */ public static function instance( ?string $file = null ): Plugin { if ( null === self::$instance ) { self::$instance = new self( (string) $file ); } return self::$instance; } /** * De repository. De enige weg naar focusdata. * * @return FocusRepository */ public function focus(): FocusRepository { return $this->focus; } /** * De toepassingspolicy. Eén instantie, zodat de hard-crop-cache gedeeld is. * * @return ApplyPolicy */ public function policy(): ApplyPolicy { return $this->policy; } /** * Absoluut pad binnen de plugin. * * @param string $relative Relatief pad. * @return string */ public function path( string $relative = '' ): string { return plugin_dir_path( $this->file ) . ltrim( $relative, '/' ); } /** * URL binnen de plugin. * * @param string $relative Relatief pad. * @return string */ public function url( string $relative = '' ): string { return plugin_dir_url( $this->file ) . ltrim( $relative, '/' ); } /** * De pluginversie, uit de header. * * @return string */ public function version(): string { return defined( 'YINGA_FOCUS_VERSION' ) ? YINGA_FOCUS_VERSION : '0.0.0'; } /** * Start de plugin. Idempotent. */ public function boot(): void { if ( $this->booted ) { return; } $this->booted = true; ( new MetaRegistrar() )->register(); ( new Controller( $this->focus ) )->register(); // De drie routes naar een `` op de frontend. Ze registreren zich // altijd; ApplyPolicy beslist per afbeelding of er iets gebeurt. Dat is // goedkoper dan hier al aannames doen over de context, en het houdt het // gedrag op één plek. ( new ImageFilters( $this->policy ) )->register(); ( new ContentFilters( $this->policy ) )->register(); ( new BlockFilters( $this->policy ) )->register(); /** * De uitbreidbare componenten. De Pro-plugin levert hier de paginascan * en de Elementor-integratie; zonder Pro blijven ze null en draait de * kern volledig zelfstandig. De kern kent Pro niet — Pro kent de kern. * * @param object|null $component Null, of een object met register(). * @param Plugin $plugin De plugin-instantie. */ $scan = apply_filters( 'yinga_focus/scan', null, $this ); if ( is_object( $scan ) && method_exists( $scan, 'register' ) ) { $scan->register(); } else { $scan = null; } $elementor = apply_filters( 'yinga_focus/elementor', null, $this ); if ( is_object( $elementor ) && method_exists( $elementor, 'register' ) ) { $elementor->register(); } else { $elementor = null; } // De adminbalk als laatste: die rapporteert over alle routes samen, en // meldt óók netjes wat er niet is. ( new AdminBar( $this->policy, $elementor, $scan ) )->register(); // De mediabibliotheek-koppeling draait alleen in de admin. Op de // frontend is er niets te bewerken, dus laden we er ook niets. if ( is_admin() ) { ( new AttachmentFields( $this->focus ) )->register(); ( new AttachmentJs( $this->focus ) )->register(); ( new Assets( $this ) )->register(); ( new Settings( $this->file ) )->register(); } add_action( 'init', array( $this, 'load_textdomain' ) ); /** * Vuurt nadat de plugin is opgestart. * * Het aanhaakpunt voor add-ons: de Pro-plugin registreert hier zijn * features, zodat de gratis plugin niets van zijn bestaan hoeft te weten. * * @param Plugin $plugin De plugin-instantie. */ do_action( 'yinga_focus/booted', $this ); } /** * Laadt de vertalingen. * * De Plugin Check van wordpress.org noemt deze aanroep "ontmoedigd sinds * 4.6", en dat klopt voor plugins die hun vertalingen van * translate.wordpress.org krijgen: die zet WordPress zelf klaar in * wp-content/languages/plugins/, en daar kijkt hij ook zonder deze regel. * * Maar hij kijkt alléén daar. Een .mo in de eigen languages/-map van de * plugin — zoals het Nederlands dat wij meeleveren — vindt WordPress niet * zonder deze aanroep. Zolang er op translate.wordpress.org nog geen * Nederlands taalpakket staat, is dit dus de enige reden dat de plugin in * het Nederlands verschijnt. Weghalen kan zodra het taalpakket er is. */ public function load_textdomain(): void { load_plugin_textdomain( Naming::TEXT_DOMAIN, false, dirname( plugin_basename( $this->file ) ) . '/languages' ); } }