Разширяване на Symelo Image Optimizations

За разработчици на добавки. Symelo Image Optimizations оптимизира изображения с библиотеките за изображения на PHP (Imagick и GD). Добавките могат да регистрират още механизми (енкодери за JPEG, PNG, WebP, AVIF, PDF или преоразмеряване), да добавят карти и раздели към екрана на плъгина, както и предупреждения, бележки, системна информация и полета за състоянието. Този документ е договорът: всичко описано тук продължава да работи в рамките на версия 1.x на API.

Съдържание:

  1. Версии
  2. Зареждане на добавка
  3. Хукове
  4. Механизми
  5. Скорост на фоновата обработка
  6. Административен екран
  7. Състояние, Здраве на сайта и системна информация
  8. Файлове, опции и почистване
  9. Правила за сигурност
  10. Публични класове

Версии

SYMELO_IMAGES_API_VERSION е низ във формат major.minor, в момента 1.0. Дефинира се само когато плъгинът реално работи (PHP 7.4 или по-нова версия), преди да се задейства symelo_images_loaded.

  • Второстепенните версии (1.1, 1.2, …) само добавят: нови хукове, нови параметри в края на хук, нови публични методи, нови методи с реализация по подразбиране в AbstractEngine, нови свойства на Job, нови задачи в Settings::TASKS, нови ключове в масиви (състояние, профили, секции на системната информация), нови CSS класове.
  • Основните версии (2.0) могат да нарушат съвместимостта. Несъвместими промени са: премахване или преименуване на хук, публичен клас, метод или константа, описани тук; промяна на параметрите или на типа на връщаната стойност на хук или метод; промяна на значението на свойство на Job, на име на задача или на ключ на профил; добавяне на метод към EngineInterface; премахване на CSS клас или атрибут data-, изброени в Административен екран.
  • EngineInterface не се променя в рамките на 1.x. Незадължителните възможности на механизмите, добавени по-късно, идват като методи на AbstractEngine с реализация по подразбиране, така че механизмите, които го наследяват, продължават да работят. Директното имплементиране на EngineInterface е позволено, но тогава не получавате тези реализации по подразбиране.
  • Всичко, което не е описано в този документ (други класове, частни и вътрешни методи, структурата на опцията с настройки, таблиците в базата данни, admin-post действията и nonce кодовете symelo_images_*), е вътрешно и може да се промени във всяка версия.

Проверете версията, преди да използвате каквото и да е:

function my_addon_api_ok(): bool {
	if ( ! defined( 'SYMELO_IMAGES_API_VERSION' ) ) {
		return false; // Not installed, not active, or PHP too old.
	}
	$version = (string) SYMELO_IMAGES_API_VERSION;
	return 1 === (int) $version && version_compare( $version, '1.0', '>=' ); // Major 1, at least 1.0.
}

Зареждане на добавка

  • Добавете Requires Plugins: symelo-image-optimizations в заглавката на добавката. Тогава WordPress 6.5 и по-новите версии няма да активират добавката без плъгина и няма да деактивират плъгина, докато добавката е активна. Въпреки това защитете всичко с проверки: при WordPress 6.4 или когато файловете са премахнати ръчно, добавката се зарежда и без плъгина.
  • Плъгините се зареждат по азбучния ред на папките си, а плъгините, активирани за мрежата, се зареждат преди тези на сайта, така че добавката може да се зареди преди или след Symelo Image Optimizations. Закачете се по следния начин:
if ( did_action( 'symelo_images_loaded' ) ) {
	my_addon_start( \Symelo\Images\Plugin::instance() );
} else {
	add_action( 'symelo_images_loaded', 'my_addon_start' );
}
// Still not started once every plugin is loaded: show an admin notice.
add_action( 'plugins_loaded', 'my_addon_check', 20 );
  • В my_addon_start() първо проверете версията на API. Преди това не зареждайте нищо, което наследява или имплементира клас на плъгина (например механизми): без плъгина PHP би спрял с фатална грешка. Основният файл на добавката, нейният autoloader и кодът ѝ за начално зареждане трябва да работят без плъгина.
  • Деактивирането на Symelo Image Optimizations никога не трябва да поврежда сайта: тогава добавката само показва известие („Install and activate Symelo Image Optimizations“).

Хукове

Действия

ДействиеАргументиКога се задейства
symelo_images_loadedPlugin $pluginВеднъж, в края на зареждането на плъгина, докато се зареждат плъгините. Тук закачете добавката си.
symelo_images_register_enginesEngineManager $enginesВсеки път, когато се изгражда списъкът с механизми: при първото използване в рамките на заявка (отложено, напр. когато се оптимизира изображение, на екрана на плъгина, при REST GET /status, в Здраве на сайта) и отново след Plugin::reset_engines() (след запазване на настройките). Извикайте $engines->add( $engine ). Не пазете референция към мениджъра.
symelo_images_file_optimizedFileRecord $after, FileRecord $beforeСлед като файл е оптимизиран, оптимизацията му е неуспешна, бил е пропуснат или е възстановен. Само за четене: не променяйте файлове тук.
symelo_images_engines_tabPlugin $pluginВ края на раздела Engines, след собствените му карти. Изведете картите си тук.
symelo_images_tab_{$slug}Plugin $pluginИзвежда панела на раздел, добавен чрез symelo_images_tabs. Всеки раздел се извежда при всяко зареждане на екрана и се показва при щракване.

Филтри

ФилтърАргументиВръщаЗа какво служи
symelo_images_capabilitystring $capability ('manage_options')ПравоКой може да използва екрана на плъгина, масовата оптимизация и REST API. Прочетете го с Plugin::capability().
symelo_images_engine_orderstring[] $ids, string $taskID на механизмиАвтоматичният ред за дадена задача. $ids вече е сортиран по ранг; пренаредете или премахнете ID. Непознатите ID и механизмите, които не обработват задачата, се пренебрегват.
symelo_images_tabsarray $tabs ([])slug => labelДопълнителни раздели, показани преди Guide и Support. Slug стойностите минават през sanitize_key(); вградените slug стойности (overview, compression, delivery, folders, tools, advanced, guide, support) се пренебрегват.
symelo_images_warningsstring[] $warnings, Plugin $pluginНизове с обикновен текстПредупреждения, показвани в раздела Overview (по едно известие за всяко), в системната информация, в wp symelo-images status и в GET /status.
symelo_images_notesstring[] $notes, Plugin $pluginНизове с обикновен текстБележки, показвани под таблицата с механизми в раздела Engines, в системната информация и в GET /status.
symelo_images_system_infoarray $sections, Plugin $plugintitle => [ label => value ]Секциите на системната информация в раздела Support (обикновен текст). Добавете своя собствена секция. Никога не включвайте пароли, ключове или токени.
symelo_images_rest_statusarray $status, Plugin $pluginМасивОтговорът на GET /wp-json/symelo-images/v1/status. Добавете един собствен ключ (напр. my_addon); не променяйте съществуващите ключове.
symelo_images_pacearray $profile, string $speedПрофилПрофилите на Background speed (вижте Скорост на фоновата обработка).
symelo_images_max_pixelsint $pixels (60 000 000)ПикселиПо-големите изображения се пропускат.
symelo_images_max_bytesint $bytes (100 MB)БайтовеПо-големите файлове се пропускат.
symelo_images_imagick_limitsarray $limitsОграниченияОграниченията на ресурсите на ImageMagick (име на константа RESOURCETYPE_* => стойност).
symelo_images_worker_budgetint $secondsСекундиКолко дълго работи едно фоново изпълнение (минимум 5).
symelo_images_dispatch_argsarray $argsАргументи за wp_remote_post()Заявката, която сайтът изпраща към самия себе си, за да стартира фонови изпълнения.
symelo_images_skip_pagebool $skip (false)Booltrue пропуска обработката за <picture> и отложено зареждане за текущата заявка.
symelo_images_more_from_symeloarray $products ([])Продукти„More from Symelo LTD“ в раздела Support.

Тестове за Здраве на сайта: използвайте филтъра site_status_tests на ядрото с ID на тестове със собствен префикс; не е нужно нищо от този плъгин.

Механизми

Механизмът кодира файлове за една или повече задачи: jpeg (компресиране на JPEG), png (компресиране на PNG), webp (копия в WebP), avif (копия в AVIF), pdf (компресиране на PDF) и resize (мащабиране и завъртане, използва се и за подготовка на копия за механизми, които не могат да правят това). Settings::TASKS ги изброява. Плъгинът включва imagick и gd; нито един вграден механизъм не обработва pdf.

Регистриране

use Symelo\Images\Engines\AbstractEngine;
use Symelo\Images\Engines\EngineException;
use Symelo\Images\Engines\EngineManager;
use Symelo\Images\Engines\Job;

final class My_Webp_Engine extends AbstractEngine {

	public function id(): string {
		return 'my-webp';
	}

	public function label(): string {
		return 'My WebP encoder';
	}

	public function tasks(): array {
		return array( 'webp' => $this->works() ? true : __( 'The encoder is missing.', 'my-addon' ) );
	}

	public function rank( string $task ): int {
		return 10; // Before Imagick (50) and GD (60).
	}

	public function accepts( Job $job ): bool {
		return $this->can( $job->task ) && in_array( $job->info->format, array( 'jpeg', 'png' ), true ) && ! $job->needs_preparing();
	}

	public function run( Job $job, string $dest ): void {
		if ( ! my_encode( $job->source(), $dest, $job->quality ) ) {
			throw new EngineException( esc_html__( 'My encoder failed.', 'my-addon' ) );
		}
	}

	private function works(): bool {
		return true;
	}
}

add_action(
	'symelo_images_register_engines',
	static function ( EngineManager $engines ) {
		$engines->add( new My_Webp_Engine() );
	}
);

EngineManager::add() заменя механизъм със същото ID; remove( $id ) премахва механизъм. ID трябва да е това, което връща sanitize_key() (малки латински букви, цифри, _, -), и не може да бъде auto. Правете ги отличими: добавяйте префикс, освен ако ID не е името на добре известна програма (cwebp).

EngineInterface

МетодДоговор
id(): stringУникално и постоянно ID. Записва се като избора на администратора за дадена задача, затова никога не го променяйте.
label(): stringИмето, което виждат администраторите.
origin(): stringОткъде идва механизмът, показва се под името му (напр. „PHP extension“, „Installed on the server“), или ''.
version(): stringОткритата версия или ''. При '' механизъм, който не може да прави нищо, показва Not found; при наличие на версия — Outdated.
note(): stringЕдно съобщение с обикновен текст за механизма (защо не е наличен или предупреждение), или ''.
tasks(): arrayВсяка задача, която механизмът обработва, и дали работи на този сървър: task => true или task => 'reason' (обикновен текст). Пропуснете задачите, които той никога не обработва. Извиква се често: кеширайте скъпите проверки (за текущата заявка или в опция с отпечатък).
rank( string $task ): intПозиция в автоматичния ред: по-ниските стойности са първи. Imagick е 50, а GD — 60 за всяка задача; AbstractEngine::RANK е 100. Специализираните енкодери, които превъзхождат библиотеките на PHP, връщат по-малко от 50.
explicit_only(): booltrue: никога не се избира от Automatic, а само когато администраторът го посочи за задача (напр. механизъм със загуби, който прави компромиси със сигурността).
can_transform(): boolДали самият механизъм прилага EXIF ориентацията и мащабирането (Job::$resize). Вижте Подготвени копия.
accepts( Job $job ): boolДали приема конкретния файл (формат, анимация, цветово пространство, размер, памет, възможности на PDF…). Отказът е нормален и евтин: заданието получава следващият механизъм. Не трябва да записва нищо.
run( Job $job, string $dest ): voidКодира в $dest. При неуспех хвърля EngineException (вижте Грешки и резултати).

AbstractEngine имплементира всичко освен id(), label(), tasks() и run(): без произход, версия или бележка, ранг static::RANK (100), не е само за изричен избор, не може да трансформира, accepts() = can( $job->task ). Добавя и can( string $task ): bool (задачата е true в tasks()). EngineManager::can( $engine, $task ) прави същото за всеки механизъм.

Рангове и автоматичен ред

За дадена задача редът се изгражда от всички регистрирани механизми, в чийто tasks() присъства тази задача (независимо дали са използваеми на този сървър):

  1. сортирани по rank( $task ), като по-ниските са първи; при равни рангове се запазва редът на регистриране (Imagick, GD, след това добавките в реда, в който са извикали add());
  2. прекарани през symelo_images_engine_order ($ids, $task), който може да пренарежда или премахва ID.

Този ред е това, което показва разделът Engines. За да оптимизира файл, плъгинът опитва последователно:

  1. механизма, който администраторът е избрал за задачата (Engine for each job), ако все още е регистриран и работи на този сървър;
  2. всички останали механизми в реда, с изключение на тези само за изричен избор;

и използва първия, в чийто tasks() задачата е true и чийто accepts() връща true. Ако run() не успее, се опитва следващият. Механизмът, показан като Automatic (…), е първият, който по принцип работи за задачата (EngineManager::preferred()).

Изборът за всяка задача се проверява спрямо регистрираните механизми: ако запазите механизъм, който е регистриран, но не може да изпълни задачата на този сървър, се показва съобщението „engine can't do that job on this server, so Automatic is used instead.“ Запазен избор за механизъм, който вече не е регистриран (добавката е деактивирана), безшумно се третира като Automatic (EngineManager::choice() връща auto) и се премахва при следващото запазване на раздела Engines.

Job

Job описва едно задание. Механизмите четат свойствата му и никога не ги променят (плъгинът подава същото задание на следващия механизъм).

Свойство / методЗначение
string $taskЗадачата (Settings::TASKS).
ImageInfo $infoИзточникът: path, format (jpeg, png, gif, webp, avif, pdf, разпознат по съдържанието), bytes, width, height, animated, alpha, cmyk, bit_depth, orientation (EXIF, 1–8), has_icc, srgb_icc, jpeg_quality (приблизителна оценка, 0 когато е неизвестна).
source(): stringАбсолютният път до файла източник ($info->path). Четете от него; никога не записвайте в него.
int $qualityОт 1 до 100 или 0 за без загуби. За jpeg при 0 е допустима само оптимизация без загуби.
?array $resize[width, height], до които да се мащабира, или null.
bool $stripПремахване на EXIF/XMP/IPTC. Плъгинът и сам премахва метаданните от резултатите в JPEG, PNG и WebP, като запазва цветовия профил и ориентацията, така че запазването на маркерите е безопасно.
bool $lossy_pngЗадача png: разрешено е намаляване на цветовете.
string $pdf_presetЗадача pdf: '' без загуби (ниво Lossless), printer умерено (Balanced, Custom), ebook по-малък файл (Aggressive). Механизмите без загуби го пренебрегват.
int $threadsНишки на енкодера според Background speed (0 = стойността по подразбиране на енкодера).
needs_preparing(): boolПикселите трябва да бъдат мащабирани ($resize) или завъртени (JPEG с orientation > 1).
with_source( ImageInfo $info ): JobКопие, което чете друг файл, с изчистено resize.
libavif_quality(): int$quality, преобразувано към скалата на libavif (за AVIF енкодери, базирани на libavif).

Подготвени копия

Механизмите, които не могат да завъртат или мащабират, връщат false от can_transform() и отказват (accepts() → false) заданията, за които needs_preparing() е вярно. Тогава плъгинът създава PNG без загуби, който вече е завъртян и мащабиран (с механизма за resize, Imagick или GD), и извиква accepts() отново с $job->with_source( $prepared ). Механизъм, който не декодира пиксели (например оптимизатор на JPEG без загуби, който запазва EXIF ориентацията), може да приема завъртени JPEG файлове, стига $resize да е null.

Грешки и резултати

  • run() записва резултата в $dest, който е нов път (презапишете го, ако съществува). По време на оптимизация това е нов файл в частната временна папка на плъгина, който плъгинът изтрива след това; самотестът на доставянето записва тестови копия в uploads/symelo-images/public/. Не записвайте никъде другаде освен собствени временни файлове в Paths::temp_dir() и ги изтривайте преди връщане, включително при неуспех.
  • При неуспех хвърлете EngineException със съобщение за администраторите, екранирано като всяко съобщение на изключение в WordPress: new EngineException( esc_html__( '…', 'my-addon' ) ) или esc_html( sprintf( … ) ). Плъгинът съхранява $e->plain_message(), което отменя това екраниране, и екранира отново навсякъде, където го извежда. Съобщението се показва заедно с файла и се опитва следващият механизъм.
  • Когато механизмът е сработил, но резултатът не може да бъде по-малък, хвърлете EngineException::no_gain(): плъгинът спира да опитва други механизми за това задание и запазва това, което има.
  • След run() плъгинът проверява резултата: съдържанието му трябва да е в очаквания формат (разпознат по байтовете), резултатите в същия формат се запазват само ако са осезаемо по-малки (с 1 KB или 1%, освен при преоразмеряване), копията в WebP и AVIF — само ако са по-малки от файла (а AVIF копието — и по-малко от WebP копието), а PDF файловете — само ако резултатът е PDF и е по-малък. Записът на място е атомарен, а за оригинала първо се прави резервно копие.
  • Механизмите за PDF проверяват Image\PdfInfo::read( $job->source() ) (encrypted, signed, forms): подписаните PDF файлове никога не трябва да се презаписват.

Скорост на фоновата обработка

Queue\Pace съдържа профилите на скоростта от Advanced → Background speed (fast, normal, gentle).

КлючЗначениеfastnormalgentle
budgetСекунди, през които работи една фонова порция25155
pauseСекунди между порциите при масова обработка0030
niceПриоритет на процесора за програмите енкодери (0 нормален … 19 най-нисък)01019
idle_ioПриоритет „idle“ на диска за програмите енкодери (Linux ionice -c 3)ненеда
threadsНишки на енкодера (0 = стойността по подразбиране на енкодера); също в Job::$threads021
max_loadМасовата обработка изчаква, докато натоварването за 1 минута на процесорно ядро е поне толкова (0 = никога)02.00.7
  • Pace::current(): array е действащият профил (с приложен филтър symelo_images_pace). Механизъм, който стартира програми енкодери, чете nice и idle_io от него при всяко изпълнение, а броя нишки — от Job::$threads.
  • Pace::profile( string $speed ): array връща един профил; Pace::SPEEDS изброява скоростите.
  • Pace::busy( array $profile ): bool, Pace::load_per_core(): ?float и Pace::cpu_count(): int показват дали сървърът е натоварен, за ваша собствена фонова работа.
  • Качванията и изричните изпълнения („Optimize now“, WP-CLI без --paced, REST API) не изчакват паузи и не следят натоварването, но използват приоритета и нишките от профила.

Административен екран

Екранът е Медия → Image Optimizations (slug на страницата Admin\Admin::PAGE, symelo-images; ID на екрана media_page_symelo-images). Всеки раздел се извежда при всяко зареждане на страницата и се превключва в браузъра, затова картите трябва да се изобразяват бързо.

  • Карти в раздела Engines: извеждайте ги на symelo_images_engines_tab.
  • Раздели: добавете slug => label чрез symelo_images_tabs, след което изведете съдържанието на панела на symelo_images_tab_{$slug}. Плъгинът го обвива в <div class="symelo-panel" data-panel="{slug}">. Admin\Ui::url( array( 'tab' => $slug ) ) дава връзка към него; връзките с data-tab-link="{slug}" превключват разделите на място.
  • Ресурси: assets/admin.css и assets/admin.js на плъгина се зареждат на екрана. Зареждайте своите само на този екран (admin_enqueue_scripts, $hook_suffix съдържа symelo-images), със собствен идентификатор (handle).

Маркиране и помощни функции за повторна употреба (стабилни в рамките на 1.x):

Клас, атрибут или помощна функцияУпотреба
<div class="symelo-card"> с <h2>Карта.
<table class="widefat striped symelo-table">Таблица в карта.
Ui::badge( $status, $label ) → .symelo-badge .symelo-badge--{ok,warn,bad,info,muted}Значка за състояние (екранира етикета си; извеждайте я с phpcs:ignore за OutputNotEscaped и тази причина).
Ui::checkbox( $name, $checked, $label, $help, $disabled, $why ) → .symelo-checkПоле за отметка, което изпраща 0, когато не е отметнато; неактивните показват $why в .symelo-unsupported.
.description, .symelo-note, .symelo-unsupported, .symelo-inline-errorПомощен текст, бележка под състояние, защо нещо не е възможно, грешка на място.
.symelo-button-rowБутони в един ред (във <form> или <p>).
.button-link.symelo-link-danger, .button.symelo-button-dangerНеобратими действия.
data-confirm="Question?" на бутон за изпращанеИска потвърждение преди изпращане (при празна стойност пита „Are you sure?“).
.symelo-options / label.symelo-optionРадио опции със заглавие и описание.
.symelo-inline-fields, table.symelo-meta, details.symelo-details, textarea.symelo-code с бутон data-copy="#id"Полета в един ред, таблица етикет/стойност, сгъваема секция, код за копиране.
Ui::url( array $args ), Ui::bytes( int ), Ui::time( int )URL адрес на екрана, размери на файлове, дати в часовата зона на сайта.
Admin\Notices::flash( $type, $message )Съобщение с обикновен текст (success, error, warning, info), показвано под заглавката, след като вашият обработчик пренасочи обратно.

Формуляри и обработчици:

  • Изпращайте към admin-post.php с действие със собствен префикс (admin_post_{your_prefix}_{action}). Никога не изпращайте към действията symelo_images_* на плъгина и не използвайте неговите nonce кодове.
  • В обработчика: първо проверете current_user_can( \Symelo\Images\Plugin::capability() ) (спрете с wp_die( …, 403 )), след това check_admin_referer( '{your_prefix}_{action}' ), след това почистете всяко поле. Пренасочете обратно с wp_safe_redirect( Ui::url( array( 'tab' => 'tools' ) ) ); exit;.
  • След като промените нещо, което засяга механизмите, извикайте Plugin::instance()->reset_engines(), за да се изгради отново списъкът с механизми при следващото използване.
  • REST маршрути: собствено пространство от имена, permission_callback, който проверява Plugin::capability(), и схеми на аргументите за всеки вход.

Състояние, Здраве на сайта и системна информация

  • symelo_images_warnings / symelo_images_notes: низове с обикновен текст (вижте Филтри). Предупрежденията са за неща, които администраторът трябва да поправи (енкодер с известни пробиви в сигурността); бележките са неутрална информация. Собственият тест на плъгина в Здраве на сайта „Image libraries are up to date“ обхваща само неговите библиотеки; добавяйте свои тестове за Здраве на сайта чрез site_status_tests на ядрото.
  • symelo_images_system_info: $sections['My Add-on'] = array( 'Version' => '1.2.3', … ). Стойностите са обикновен текст.
  • symelo_images_rest_status: $status['my_addon'] = array( … ).

Файлове, опции и почистване

  • Плъгинът притежава uploads/symelo-images/ (backups/, tmp/, public/) и изтрива uploads/symelo-images/tools/ (папка от предварителни версии), когато бъде инсталиран или обновен. Съхранявайте файловете на добавката в собствена папка, например uploads/{your-slug}/, защитена като тази на плъгина (index.php, .htaccess с Require all denied, web.config).
  • Support\Paths::temp_dir() е частната временна папка на плъгина, за краткотрайни файлове на механизмите. Файловете, по-стари от един ден, се изтриват ежедневно; изтривайте своите веднага.
  • Съхранявайте настройките в собствена опция. Никога не записвайте в symelo_images_settings, в таблицата на плъгина или в другите му опции.
  • Когато плъгинът бъде изтрит, той премахва transient записите, чиито имена започват със symelo_images_, затова transient записите на добавката с такива имена трябва да са само кеш.
  • Почиствайте при собственото си деинсталиране (uninstall.php), без да зареждате плъгина.

Правила за сигурност

Добавките трябва да спазват правилата на плъгина:

  • Синтаксис на PHP 7.4 и API на WordPress 6.4, освен ако добавката не изисква по-нови версии.
  • Първо право, после nonce, във всеки обработчик; почиствайте входа, екранирайте изхода, използвайте $wpdb->prepare() за всяка заявка.
  • Никога не приемайте път до файл или програма от заявка или настройка; работете само с Job::source(), $dest и папки, които притежавате.
  • Стартирайте програми само с масиви от аргументи (без shell), минимална среда и ограничения на времето и отказвайте версии с известни пробиви в сигурността.
  • Съобщенията в EngineException се екранират там, където се хвърлят.

Публични класове

Стабилни в рамките на API 1.x (пространство от имена Symelo\Images):

КласПубличен API
Plugininstance(), capability(), settings(), engines(), reset_engines()
Engines\EngineInterface, Engines\AbstractEngineКакто е описано по-горе
Engines\EngineManageradd(), remove(), all(), get(), order(), candidates(), choice(), preferred(), supports(), can() (статичен), usable_tasks() (статичен)
Engines\JobСвойствата и методите по-горе
Engines\EngineExceptionNO_GAIN, no_gain(), plain_message()
Image\ImageInfoПубличните свойства, read(), sniff(), read_bytes(), pixels(), is_image()
Image\PdfInforead()
Queue\PaceSPEEDS, profile(), current(), busy(), load_per_core(), cpu_count()
Settings\SettingsTASKS (самите ключове на настройките не са част от API)
Support\Pathstemp_dir()
Support\SystemPackagesfind(), is_patched() (версии на пакети в Debian/Ubuntu с пренесени поправки за сигурност)
Admin\AdminPAGE
Admin\Uiurl(), badge(), checkbox(), bytes(), time()
Admin\Noticesflash()

extending.md