renderSummary(); $this->renderTriggers(); $this->renderTables(); $this->renderFootprint(); Ui::pageClose(); } /** * The four figures worth seeing before anything else. */ private function renderSummary(): void { $stats = Queue::stats(); $since = Dispatcher::secondsSinceLastRun(); Ui::statsOpen(); if ( null === $since ) { $lastRun = Ui::stat( '—', __( 'آخرین اجرای ورکر', 'rahkar-toolkit' ), __( 'هرگز اجرا نشده', 'rahkar-toolkit' ), 'warning' ); } else { $lastRun = Ui::stat( human_time_diff( time() - $since ), __( 'آخرین اجرای ورکر', 'rahkar-toolkit' ), $since > 900 ? __( 'احتمالاً هیچ محرکی فعال نیست', 'rahkar-toolkit' ) : '', $since > 900 ? 'warning' : 'success' ); } echo wp_kses( $lastRun, Ui::allowedHtml() ); echo wp_kses( Ui::stat( number_format_i18n( $stats['pending'] ), __( 'در انتظار', 'rahkar-toolkit' ) ), Ui::allowedHtml() ); echo wp_kses( Ui::stat( number_format_i18n( $stats['reserved'] ), __( 'در حال پردازش', 'rahkar-toolkit' ) ), Ui::allowedHtml() ); echo wp_kses( Ui::stat( number_format_i18n( $stats['failed'] ), __( 'ناموفق', 'rahkar-toolkit' ), $stats['failed'] > 0 ? __( 'بررسی گزارش‌ها توصیه می‌شود', 'rahkar-toolkit' ) : '', $stats['failed'] > 0 ? 'error' : '' ), Ui::allowedHtml() ); Ui::statsClose(); } /** * The three independent ways background work gets run. */ private function renderTriggers(): void { $hasFastcgi = function_exists( 'fastcgi_finish_request' ); Ui::panelOpen( __( 'محرک‌های اجرا', 'rahkar-toolkit' ), __( 'کارهای پس‌زمینه این افزونه به کرون وردپرس وابسته نیستند. سه محرک مستقل وجود دارد و هرکدام به‌تنهایی کافی است.', 'rahkar-toolkit' ), 'gauge' ); Ui::tableOpen( [ __( 'محرک', 'rahkar-toolkit' ), __( 'وضعیت', 'rahkar-toolkit' ), __( 'توضیح', 'rahkar-toolkit' ) ] ); $this->triggerRow( __( '۱. اجرا پس از ارسال پاسخ', 'rahkar-toolkit' ), Ui::badge( __( 'فعال', 'rahkar-toolkit' ), 'success' ), $hasFastcgi ? __( 'پاسخ کاربر بسته می‌شود و بعد کارها اجرا می‌شوند. هیچ تأخیری برای بازدیدکننده ایجاد نمی‌شود.', 'rahkar-toolkit' ) : __( 'روی این سرور fastcgi_finish_request در دسترس نیست؛ از حالت جایگزین استفاده می‌شود. راه‌اندازی کرون واقعی سرور توصیه می‌شود.', 'rahkar-toolkit' ) ); $this->triggerRow( __( '۲. کرون واقعی سرور', 'rahkar-toolkit' ), Ui::badge( __( 'دستی', 'rahkar-toolkit' ), 'quiet' ), __( 'تنها محرکی که در نبود بازدیدکننده هم کار می‌کند. این خط را در کران‌تب سرور قرار دهید:', 'rahkar-toolkit' ), Ui::codeBlock( WorkerEndpoint::cronLine() ) ); $this->triggerRow( __( '۳. لوپ‌بک', 'rahkar-toolkit' ), Ui::badge( __( 'فعال', 'rahkar-toolkit' ), 'success' ), __( 'برای کارهای فوری، حداکثر هر ۶۰ ثانیه یک‌بار.', 'rahkar-toolkit' ) ); $this->triggerRow( __( 'کرون وردپرس', 'rahkar-toolkit' ), Ui::badge( __( 'استفاده نمی‌شود', 'rahkar-toolkit' ), 'quiet' ), defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ? __( 'غیرفعال است و این مشکلی ایجاد نمی‌کند.', 'rahkar-toolkit' ) : __( 'فعال است ولی این افزونه از آن استفاده نمی‌کند.', 'rahkar-toolkit' ) ); Ui::tableClose(); Ui::panelClose(); } /** * One row of the triggers table. * * @param string $name Trigger name. * @param string $status Pre-escaped badge markup. * @param string $note Explanation. * @param string $extra Optional pre-escaped markup under the explanation. */ private function triggerRow( string $name, string $status, string $note, string $extra = '' ): void { printf( '%s%s%s%s', esc_html( $name ), wp_kses( $status, Ui::allowedHtml() ), esc_html( $note ), wp_kses( $extra, Ui::allowedHtml() ) ); } /** * Table presence — catches a half-finished activation. */ private function renderTables(): void { Ui::panelOpen( __( 'جدول‌های دیتابیس', 'rahkar-toolkit' ), '', 'package' ); Ui::tableOpen( [ __( 'جدول', 'rahkar-toolkit' ), __( 'وضعیت', 'rahkar-toolkit' ) ], true ); // `tables()` rather than the constant, so a table an add-on contributed is // checked here too — a pro module whose table never got created would // otherwise fail silently at the first write. foreach ( array_keys( Schema::tables() ) as $key ) { $exists = Schema::exists( $key ); printf( '%s%s', wp_kses( Ui::badge( Schema::table( $key ), 'quiet', true ), Ui::allowedHtml() ), wp_kses( $exists ? Ui::badge( __( 'موجود', 'rahkar-toolkit' ), 'success' ) : Ui::badge( __( 'ساخته نشده', 'rahkar-toolkit' ), 'error' ), Ui::allowedHtml() ) ); } Ui::tableClose(); Ui::panelClose(); } /** * What the plugin costs a request. */ private function renderFootprint(): void { $size = Manifest::size(); $overSize = $size > Manifest::SIZE_BUDGET; $enabled = Manifest::enabledModules(); $opcache = function_exists( 'opcache_get_status' ) && @opcache_get_status( false ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged $ui = Ui::loadedVersion(); $stale = Ui::missingComponents(); Ui::panelOpen( __( 'ردپای افزونه', 'rahkar-toolkit' ), '', 'chart' ); Ui::tableOpen( [ __( 'مورد', 'rahkar-toolkit' ), __( 'وضعیت', 'rahkar-toolkit' ) ] ); $this->footprintRow( __( 'حجم مانیفست (autoload)', 'rahkar-toolkit' ), sprintf( /* translators: 1: current size in bytes, 2: budget in bytes */ __( '%1$s بایت از بودجه %2$s بایت', 'rahkar-toolkit' ), number_format_i18n( $size ), number_format_i18n( Manifest::SIZE_BUDGET ) ), $overSize ? Ui::badge( __( 'بیش از بودجه', 'rahkar-toolkit' ), 'warning' ) : Ui::badge( __( 'در بودجه', 'rahkar-toolkit' ), 'success' ) ); $this->footprintRow( __( 'ماژول‌های روشن', 'rahkar-toolkit' ), [] === $enabled ? __( 'هیچ‌کدام — افزونه عملاً هیچ کاری روی سایت انجام نمی‌دهد.', 'rahkar-toolkit' ) : implode( '، ', $enabled ), '' ); $this->footprintRow( 'OPcache', $opcache ? '' : __( 'روشن کردن آن تأثیر زیادی روی سرعت دارد.', 'rahkar-toolkit' ), $opcache ? Ui::badge( __( 'فعال', 'rahkar-toolkit' ), 'success' ) : Ui::badge( __( 'غیرفعال', 'rahkar-toolkit' ), 'warning' ) ); // A missing design system shows up as an unstyled screen and nothing else, // which is a confusing thing to debug from the outside. $this->footprintRow( __( 'دیزاین سیستم', 'rahkar-toolkit' ), '' === $ui ? __( 'نسخه‌ی همراه افزونه پیدا نشد؛ صفحه‌ها بدون استایل نمایش داده می‌شوند.', 'rahkar-toolkit' ) : '', '' === $ui ? Ui::badge( __( 'لود نشد', 'rahkar-toolkit' ), 'error' ) : Ui::badge( $ui, 'quiet', true ) ); // A vendored copy can be present, load cleanly, report a version, and still // be missing a component a screen renders markup for. That combination has // no symptom except an unstyled block in the middle of an otherwise styled // page, so it gets its own row rather than being folded into the one above. if ( [] !== $stale ) { $this->footprintRow( __( 'بیلد وندورشده', 'rahkar-toolkit' ), sprintf( /* translators: %s: comma-separated component names */ __( 'این کامپوننت‌ها در بیلد همراه افزونه نیستند: %s — دستور bin/sync-ui.php را اجرا کنید.', 'rahkar-toolkit' ), implode( '، ', $stale ) ), Ui::badge( __( 'عقب‌تر از کد', 'rahkar-toolkit' ), 'warning' ) ); } Ui::tableClose(); Ui::panelClose(); } /** * One row of the footprint table. * * @param string $label What is being reported. * @param string $note Plain-text detail, may be empty. * @param string $status Pre-escaped badge markup, may be empty. */ private function footprintRow( string $label, string $note, string $status ): void { printf( '%s%s%s', esc_html( $label ), wp_kses( $status, Ui::allowedHtml() ), '' === $note ? '' : sprintf( '

%s

', esc_html( $note ) ) ); } }