Add Hungarian language support and update author and repository metadata
Tests / tests (push) Successful in 5s
Release / upload-asset (push) Successful in 4s

This commit is contained in:
sandros committed 2026-09-27 23:08:51 +02:00
1 parent 7a0aa56433
commit a30722c751
12 files changed
+388 -72

No files matched your search

+4
View File
@@ -8,7 +8,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## 3.4.1 - 2026-09-27
### Added
- Hungarian language support (hu_HU) with .pot, .po, and .mo files
### Changed
- credited sandros & Rarst as authors and updated repository homepage
- adjusted requirements to `Requires at least: 6.2` to support ClassicPress 2.x and WordPress 6.2+
- updated documentation with Hungarian translation
+6 -2
View File
@@ -3,16 +3,20 @@
"description": "Light WordPress profiler.",
"keywords" : ["wordpress", "performance"],
"type" : "wordpress-plugin",
"homepage" : "https://github.com/Rarst/laps",
"homepage" : "https://git.sandros.hu/sandros/laps",
"license" : "MIT",
"authors" : [
{
"name" : "sandros",
"homepage": "https://git.sandros.hu/sandros"
},
{
"name" : "Andrey Savchenko",
"homepage": "https://www.Rarst.net/"
}
],
"support" : {
"issues": "https://github.com/Rarst/laps/issues"
"issues": "https://git.sandros.hu/sandros/laps/issues"
},
"autoload" : {
"psr-4": {
Binary file not shown.
+150
View File
@@ -0,0 +1,150 @@
# Hungarian translation for Laps.
# Copyright (C) 2026 sandros & Rarst
# This file is distributed under the MIT license.
#
msgid ""
msgstr ""
"Project-Id-Version: Laps 3.4.1\n"
"Report-Msgid-Bugs-To: https://git.sandros.hu/sandros/laps/issues\n"
"POT-Creation-Date: 2026-09-27 23:05+0200\n"
"PO-Revision-Date: 2026-09-27 23:06+0200\n"
"Last-Translator: sandros <me@sandros.hu>\n"
"Language-Team: Hungarian <hu_HU@li.org>\n"
"Language: hu_HU\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. Description of the plugin
#: laps.php:5
msgid "Light WordPress profiler."
msgstr "Könnyűsúlyú WordPress profilozó."
#. translators: %s: page load time in seconds
#: src/Manager/Toolbar_Manager.php:51
msgid "Lap: %ss"
msgstr "Kör: %ss"
#. translators: %s: PHP version
#: src/Record/Collector/Core_Load_Collector.php:40
msgid "PHP Load – %s"
msgstr "PHP betöltés – %s"
#: src/Record/Collector/Core_Load_Collector.php:48
msgid "OPcache"
msgstr "OPcache"
#: src/Record/Collector/Core_Load_Collector.php:51
msgid "Core Load"
msgstr "WordPress mag betöltése"
#: src/Record/Collector/Core_Load_Collector.php:51
msgid "Core & MU Plugins Load"
msgstr "WordPress mag és MU bővítmények betöltése"
#: src/Record/Collector/Hook_Collector.php:46
msgid "Network & MU Plugins Load"
msgstr "Hálózati és MU bővítmények betöltése"
#: src/Event/Core_Events.php:16
msgid "Plugins Load"
msgstr "Bővítmények betöltése"
#: src/Event/Core_Events.php:17
msgid "Plugins Loaded Hook"
msgstr "Plugins Loaded hook"
#: src/Event/Core_Events.php:18
msgid "Themes Load"
msgstr "Sablonok betöltése"
#: src/Event/Core_Events.php:19
msgid "Init Hook"
msgstr "Init hook"
#: src/Event/Core_Events.php:20
msgid "WP Loaded Hook"
msgstr "WP Loaded hook"
#: src/Event/Core_Events.php:21
msgid "Query Setup"
msgstr "Lekérdezés előkészítése"
#: src/Event/Core_Events.php:22
msgid "Template Loader"
msgstr "Sablon betöltő"
#: src/Event/Core_Events.php:23
msgid "Admin Init Hook"
msgstr "Admin Init hook"
#: src/Event/Core_Events.php:24
msgid "Admin Menu"
msgstr "Admin menü"
#: src/Event/Core_Events.php:25
msgid "Admin Print Scripts"
msgstr "Admin scriptek betöltése"
#: src/Event/Core_Events.php:26
msgid "Head Hook"
msgstr "Fejléc hook (wp_head)"
#: src/Event/Core_Events.php:27
msgid "Main Loop"
msgstr "Fő ciklus (loop)"
#: src/Event/Core_Events.php:28
msgid "Sidebar"
msgstr "Oldalsáv (sidebar)"
#: src/Event/Core_Events.php:29
msgid "Toolbar"
msgstr "Eszköztár (toolbar)"
#: src/Event/Core_Events.php:30
msgid "Footer Hook"
msgstr "Lábléc hook (wp_footer)"
#. translators: 1: file path, 2: line number
#: src/Formatter/Hook_Formatter.php:94
msgid "closure from %1$s:%2$d"
msgstr "closure innen: %1$s:%2$d"
#. translators: 1: file path, 2: line number
#: src/Formatter/Hook_Formatter.php:107
msgid "anonymous class from %1$s:%2$d"
msgstr "névtelen osztály innen: %1$s:%2$d"
#: src/Event/Extension_Events.php:28
msgid "Beaver Builder Post Content"
msgstr "Beaver Builder bejegyzéstartalom"
#: src/Event/Extension_Events.php:33
msgid "Beaver Builder Module"
msgstr "Beaver Builder modul"
#: src/Event/Extension_Events.php:40
msgid "Beaver Builder Top Bar"
msgstr "Beaver Builder felső sáv"
#: src/Event/Extension_Events.php:41
msgid "Beaver Builder Header"
msgstr "Beaver Builder fejléc"
#: src/Event/Extension_Events.php:42
msgid "Beaver Builder Page Content"
msgstr "Beaver Builder oldaltartalom"
#: src/Event/Extension_Events.php:43
msgid "Beaver Builder Post"
msgstr "Beaver Builder bejegyzés"
#: src/Event/Extension_Events.php:44
msgid "Beaver Builder Footer Widgets"
msgstr "Beaver Builder lábléc widgetek"
#: src/Event/Extension_Events.php:45
msgid "Beaver Builder Footer"
msgstr "Beaver Builder lábléc"
+148
View File
@@ -0,0 +1,148 @@
# Copyright (C) 2026 sandros & Rarst
# This file is distributed under the MIT license.
msgid ""
msgstr ""
"Project-Id-Version: Laps 3.4.1\n"
"Report-Msgid-Bugs-To: https://git.sandros.hu/sandros/laps/issues\n"
"POT-Creation-Date: 2026-09-27 23:05+0200\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2026-YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#. Description of the plugin
#: laps.php:5
msgid "Light WordPress profiler."
msgstr ""
#. translators: %s: page load time in seconds
#: src/Manager/Toolbar_Manager.php:51
msgid "Lap: %ss"
msgstr ""
#. translators: %s: PHP version
#: src/Record/Collector/Core_Load_Collector.php:40
msgid "PHP Load – %s"
msgstr ""
#: src/Record/Collector/Core_Load_Collector.php:48
msgid "OPcache"
msgstr ""
#: src/Record/Collector/Core_Load_Collector.php:51
msgid "Core Load"
msgstr ""
#: src/Record/Collector/Core_Load_Collector.php:51
msgid "Core & MU Plugins Load"
msgstr ""
#: src/Record/Collector/Hook_Collector.php:46
msgid "Network & MU Plugins Load"
msgstr ""
#: src/Event/Core_Events.php:16
msgid "Plugins Load"
msgstr ""
#: src/Event/Core_Events.php:17
msgid "Plugins Loaded Hook"
msgstr ""
#: src/Event/Core_Events.php:18
msgid "Themes Load"
msgstr ""
#: src/Event/Core_Events.php:19
msgid "Init Hook"
msgstr ""
#: src/Event/Core_Events.php:20
msgid "WP Loaded Hook"
msgstr ""
#: src/Event/Core_Events.php:21
msgid "Query Setup"
msgstr ""
#: src/Event/Core_Events.php:22
msgid "Template Loader"
msgstr ""
#: src/Event/Core_Events.php:23
msgid "Admin Init Hook"
msgstr ""
#: src/Event/Core_Events.php:24
msgid "Admin Menu"
msgstr ""
#: src/Event/Core_Events.php:25
msgid "Admin Print Scripts"
msgstr ""
#: src/Event/Core_Events.php:26
msgid "Head Hook"
msgstr ""
#: src/Event/Core_Events.php:27
msgid "Main Loop"
msgstr ""
#: src/Event/Core_Events.php:28
msgid "Sidebar"
msgstr ""
#: src/Event/Core_Events.php:29
msgid "Toolbar"
msgstr ""
#: src/Event/Core_Events.php:30
msgid "Footer Hook"
msgstr ""
#. translators: 1: file path, 2: line number
#: src/Formatter/Hook_Formatter.php:94
msgid "closure from %1$s:%2$d"
msgstr ""
#. translators: 1: file path, 2: line number
#: src/Formatter/Hook_Formatter.php:107
msgid "anonymous class from %1$s:%2$d"
msgstr ""
#: src/Event/Extension_Events.php:28
msgid "Beaver Builder Post Content"
msgstr ""
#: src/Event/Extension_Events.php:33
msgid "Beaver Builder Module"
msgstr ""
#: src/Event/Extension_Events.php:40
msgid "Beaver Builder Top Bar"
msgstr ""
#: src/Event/Extension_Events.php:41
msgid "Beaver Builder Header"
msgstr ""
#: src/Event/Extension_Events.php:42
msgid "Beaver Builder Page Content"
msgstr ""
#: src/Event/Extension_Events.php:43
msgid "Beaver Builder Post"
msgstr ""
#: src/Event/Extension_Events.php:44
msgid "Beaver Builder Footer Widgets"
msgstr ""
#: src/Event/Extension_Events.php:45
msgid "Beaver Builder Footer"
msgstr ""
+9 -3
View File
@@ -2,14 +2,16 @@
/*
Plugin Name: Laps
Plugin URI: https://github.com/Rarst/laps
Plugin URI: https://git.sandros.hu/sandros/laps
Description: Light WordPress profiler.
Author: Andrey “Rarst” Savchenko
Author: sandros & Rarst
Author URI: https://git.sandros.hu/sandros/laps
Version: 3.4.1
Author URI: https://www.rarst.net/
Requires at least: 6.2
Requires PHP: 7.4
Update URI: false
Text Domain: laps
Domain Path: /languages
License: MIT
*/
@@ -25,6 +27,10 @@ if ( PHP_VERSION_ID < 70400 ) {
trigger_error( 'Laps requires PHP version >=7.4.', E_USER_ERROR );
}
add_action( 'plugins_loaded', function (): void {
load_plugin_textdomain( 'laps', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
} );
$laps = new \Rarst\Laps\Plugin();
$laps->run();
+60 -61
View File
@@ -4,89 +4,76 @@ declare( strict_types=1 );
namespace Rarst\Laps\Formatter;
/**
* Formatter to process callbacks from a hook instance.
* Formatter for WordPress hook callbacks.
*/
class Hook_Formatter {
/** @var array $truncate_paths Paths to truncate from includes. */
protected $truncate_paths = [];
/** @var array $truncate_paths List of base paths to strip for readability. */
protected $truncate_paths;
/**
* Set up object properties.
* Set up truncate paths.
*/
public function __construct() {
// TODO inject paths instead of reaching for global constants.
$this->truncate_paths = [
wp_normalize_path( WP_CONTENT_DIR ),
$this->truncate_paths = array_filter( [
wp_normalize_path( ABSPATH ),
'wp-admin/',
];
wp_normalize_path( WP_CONTENT_DIR ),
] );
}
/**
* @psalm-type Callback = string|object|array
* @psalm-type AcceptedArgs = int
* @psalm-type Hook = array{function: Callback, accepted_args: AcceptedArgs}
* @psalm-type Priority = array-key
* @psalm-type Hooks = array<Priority, array<Hook>>
* Convert hook callbacks array to a list of readable names.
*
* @param \WP_Hook|array $hook Hook instance.
* @psalm-param \WP_Hook|Hooks $hook
* @param array $hook Array of callbacks, registered for the hook.
*
* @return array
*/
public function format( $hook ): array {
$callbacks = [];
if ( $hook instanceof \WP_Hook ) {
/** @psalm-var Hooks $hook->callbacks */
$hook = $hook->callbacks;
}
public function format( array $hook ): array {
if ( empty( $hook ) ) {
return $callbacks;
}
ksort( $hook );
$functions = array_merge( ...$hook );
foreach ( $functions as $function ) {
$callback = $this->get_callback_name( $function['function'], $function['accepted_args'] );
if ( false !== strpos( $callback, 'Hook_Collector' ) ) {
continue;
}
$callbacks[] = $callback;
}
return $callbacks;
return [];
}
/**
* @param string|object|array $callback Hook callback.
* @param int $args Number of accepted arguments.
* Empty priorities produce empty arrays in PHP 7.2 and unpack operator doesn't accept empty array in 7.3.
*
* @see https://wiki.php.net/rfc/compact-empty-array-de-optimization
* @see https://bugs.php.net/bug.php?id=76045
*/
protected function get_callback_name( $callback, int $args ): string {
$hook = array_filter( $hook );
switch ( gettype( $callback ) ) {
case 'object':
$name = $this->get_class_name( $callback );
break;
if ( empty( $hook ) ) {
return [];
}
case 'array':
/** @psalm-var array{0: object|string, 1: string} $callback */
$class = is_string( $callback[0] )
? $callback[0] . '::'
: $this->get_class_name( $callback[0] ) . '->';
$name = $class . $callback[1];
break;
/** @var array $functions */
$functions = array_merge( ...$hook );
default:
return array_map( [ $this, 'format_callback' ], $functions );
}
/**
* Convert callback data array to a readable name.
*
* @param array $callback_data Callback data, registered for the hook.
*
* @return string
*/
protected function format_callback( array $callback_data ): string {
$callback = $callback_data['function'];
$args = $callback_data['accepted_args'];
if ( is_string( $callback ) ) {
$name = $callback;
} elseif ( is_array( $callback ) ) {
$class = is_object( $callback[0] ) ? $this->get_class_name( $callback[0] ) : $callback[0];
$name = $class . '::' . $callback[1];
} elseif ( is_object( $callback ) ) {
$name = $this->get_class_name( $callback );
} else {
$name = 'unknown';
}
return $name . ( ( 1 === $args ) ? '' : "({$args})" );
@@ -102,14 +89,24 @@ class Hook_Formatter {
if ( $object instanceof \Closure ) {
$class = new \ReflectionFunction( $object );
return 'closure from ' . $this->shorten_path( $class->getFileName() ) . ':' . $class->getStartLine();
return sprintf(
/* translators: 1: file path, 2: line number */
__( 'closure from %1$s:%2$d', 'laps' ),
$this->shorten_path( (string) $class->getFileName() ),
(int) $class->getStartLine()
);
}
$class = new \ReflectionClass( $object );
$name = $class->getName();
if ( 0 === strpos( $name, 'class@anonymous' ) ) {
return 'anonymous class from ' . $this->shorten_path( $class->getFileName() ) . ':' . $class->getStartLine();
return sprintf(
/* translators: 1: file path, 2: line number */
__( 'anonymous class from %1$s:%2$d', 'laps' ),
$this->shorten_path( (string) $class->getFileName() ),
(int) $class->getStartLine()
);
}
return $name;
@@ -121,14 +118,16 @@ class Hook_Formatter {
* @return string
*/
protected function shorten_path( string $path ): string {
$path = wp_normalize_path( $path );
$path = str_replace( $this->truncate_paths, '', $path );
if ( ':' === $path[1] ) {
if ( 0 === strpos( $path, './' ) ) {
$path = substr( $path, 2 );
}
$path = ltrim( $path, '/' );
return $path;
}
}
+2 -1
View File
@@ -47,7 +47,8 @@ class Toolbar_Manager {
$wp_admin_bar->add_node( [
'id' => 'laps',
'title' => sprintf( 'Lap: %ss', round( microtime( true ) - $timestart, 3 ) ),
/* translators: %s: page load time in seconds */
'title' => sprintf( __( 'Lap: %ss', 'laps' ), round( microtime( true ) - $timestart, 3 ) ),
] );
$wp_admin_bar->add_node( [
+4 -3
View File
@@ -36,7 +36,8 @@ class Core_Load_Collector implements Record_Collector_Interface {
$request_time = filter_var( $_SERVER['REQUEST_TIME_FLOAT'], FILTER_VALIDATE_FLOAT );
$php = 'PHP Load – ' . PHP_VERSION;
/* translators: %s: PHP version */
$php = sprintf( __( 'PHP Load – %s', 'laps' ), PHP_VERSION );
if ( $this->opcache_api_available() ) {
/**
@@ -44,10 +45,10 @@ class Core_Load_Collector implements Record_Collector_Interface {
* @see https://github.com/php/php-src/issues/8799
*/
$zend_status = @opcache_get_status();
$php .= empty( $zend_status['opcache_enabled'] ) ? '' : ' – OPcache';
$php .= empty( $zend_status['opcache_enabled'] ) ? '' : ' – ' . __( 'OPcache', 'laps' );
}
$load = $this->network_activated ? 'Core Load' : 'Core & MU Plugins Load';
$load = $this->network_activated ? __( 'Core Load', 'laps' ) : __( 'Core & MU Plugins Load', 'laps' );
/**
* @var float $request_time
+2 -1
View File
@@ -52,8 +52,9 @@ class Record implements Record_Interface {
if ( empty( $this->description ) ) {
$duration = round( $this->get_duration() * 1000 );
$name = __( $this->name, 'laps' );
return "{$this->name} – {$duration}&nbsp;ms";
return "{$name} – {$duration}&nbsp;ms";
}
return $this->description;
+2 -1
View File
@@ -45,8 +45,9 @@ class Stopwatch_Record implements Record_Interface {
$duration = round( $this->stopwatch_event->getDuration() );
$memory = round( $this->stopwatch_event->getMemory() / 1024 / 1024, 2 );
$description = '' !== $this->description ? "<hr />{$this->description}" : '';
$name = __( $this->name, 'laps' );
return "{$this->name} – {$duration} ms – {$memory} MB{$description}";
return "{$name} – {$duration} ms – {$memory} MB{$description}";
}
/**
+1
View File
@@ -13,6 +13,7 @@ class LapsTestCase extends TestCase {
protected function setUp():void {
parent::setUp();
Monkey\setUp();
Monkey\Functions\stubTranslationFunctions();
}
protected function tearDown(): void {