first commit

This commit is contained in:
2023-09-12 21:41:04 +02:00
commit 3361a7f053
13284 changed files with 2116755 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
<?php
namespace WPML\ST\MO\File;
use WPML\ST\TranslationFile\StringEntity;
class Builder extends \WPML\ST\TranslationFile\Builder {
/** @var Generator */
private $generator;
public function __construct( Generator $generator ) {
$this->generator = $generator;
}
/**
* @param StringEntity[] $strings
* @return string
*/
public function get_content( array $strings ) {
return $this->generator->getContent( $strings );
}
}

View File

@@ -0,0 +1,132 @@
<?php
namespace WPML\ST\MO\File;
use WP_Filesystem_Direct;
use WPML\ST\MO\Generate\Process\Status;
use WPML\ST\MO\Generate\Process\SingleSiteProcess;
use WPML\ST\MO\Notice\RegenerationInProgressNotice;
use function wpml_get_admin_notices;
class FailureHooks implements \IWPML_Backend_Action {
use makeDir;
const NOTICE_GROUP = 'mo-failure';
const NOTICE_ID_MISSING_FOLDER = 'missing-folder';
/** @var Status */
private $status;
/** @var SingleSiteProcess $singleProcess */
private $singleProcess;
public function __construct(
WP_Filesystem_Direct $filesystem,
Status $status,
SingleSiteProcess $singleProcess
) {
$this->filesystem = $filesystem;
$this->status = $status;
$this->singleProcess = $singleProcess;
}
public function add_hooks() {
add_action( 'admin_init', [ $this, 'checkDirectories' ] );
}
public function checkDirectories() {
if ( $this->isDirectoryMissing( WP_LANG_DIR ) ) {
$this->resetRegenerateStatus();
$this->displayMissingFolderNotice( WP_LANG_DIR );
return;
}
if ( $this->isDirectoryMissing( self::getSubdir() ) ) {
$this->resetRegenerateStatus();
if ( ! $this->maybeCreateSubdir() ) {
$this->displayMissingFolderNotice( self::getSubdir() );
return;
}
}
if ( ! $this->status->isComplete() ) {
$this->displayRegenerateInProgressNotice();
$this->singleProcess->runPage();
}
if ( $this->status->isComplete() ) {
wpml_get_admin_notices()->remove_notice( RegenerationInProgressNotice::GROUP, RegenerationInProgressNotice::ID );
}
}
/**
* @param string $dir
*/
public function displayMissingFolderNotice( $dir ) {
$notices = wpml_get_admin_notices();
$notice = $notices->get_new_notice(
self::NOTICE_ID_MISSING_FOLDER, self::missingFolderNoticeContent( $dir ),
self::NOTICE_GROUP
);
$notice->set_css_classes( 'error' );
$notices->add_notice( $notice );
}
/**
* @param string $dir
*
* @return string
*/
public static function missingFolderNoticeContent( $dir ) {
$text = '<p>' .
esc_html__( 'WPML String Translation is attempting to write .mo files with translations to folder:',
'wpml-string-translation' ) . '<br/>' .
str_replace( '\\', '/', $dir ) .
'</p>';
$text .= '<p>' . esc_html__( 'This folder appears to be not writable. This is blocking translation for strings from appearing on the site.',
'wpml-string-translation' ) . '</p>';
$text .= '<p>' . esc_html__( 'To resolve this, please contact your hosting company and request that they make that folder writable.',
'wpml-string-translation' ) . '</p>';
$url = 'https://wpml.org/faq/cannot-write-mo-files/?utm_source=plugin&utm_medium=gui&utm_campaign=wpmlst';
$link = '<a href="' . $url . '" target="_blank" rel="noreferrer noopener" >' .
esc_html__( "WPML's documentation on troubleshooting .mo files generation.",
'wpml-string-translation' ) .
'</a>';
$text .= '<p>' . sprintf( esc_html__( 'For more details, see %s.', 'wpml-string-translation' ),
$link ) . '</p>';
return $text;
}
private function displayRegenerateInProgressNotice() {
$notices = wpml_get_admin_notices();
$notices->remove_notice( self::NOTICE_GROUP, self::NOTICE_ID_MISSING_FOLDER );
$notices->add_notice( new RegenerationInProgressNotice() );
}
/**
* @return string
*/
public static function getSubdir() {
return WP_LANG_DIR . '/' . \WPML\ST\TranslationFile\Manager::SUB_DIRECTORY;
}
/**
* @param string $dir
*
* @return bool
*/
private function isDirectoryMissing( $dir ) {
return ! $this->filesystem->is_writable( $dir );
}
private function resetRegenerateStatus() {
$this->status->markIncomplete();
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace WPML\ST\MO\File;
use SitePress;
use WPML\ST\MO\Generate\Process\ProcessFactory;
use function WPML\Container\make;
use WPML\ST\MO\Scan\UI\Factory as UiFactory;
class FailureHooksFactory implements \IWPML_Backend_Action_Loader {
/**
* @return FailureHooks|null
* @throws \WPML\Auryn\InjectionException
*/
public function create() {
/** @var SitePress $sitepress */
global $sitepress;
if ( $sitepress->is_setup_complete() && $this->hasRanPreGenerateViaUi() ) {
$inBackground = true;
return make( FailureHooks::class, [
':status' => ProcessFactory::createStatus( $inBackground ),
':singleProcess' => ProcessFactory::createSingle( $inBackground ),
] );
}
return null;
}
/**
* @return bool
* @throws \WPML\Auryn\InjectionException
*/
private function hasRanPreGenerateViaUi() {
$uiPreGenerateStatus = ProcessFactory::createStatus( false );
return $uiPreGenerateStatus->isComplete()
|| UiFactory::isDismissed()
|| ! ProcessFactory::createSingle()->getPagesCount();
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace WPML\ST\MO\File;
use WPML\Collect\Support\Collection;
use WPML\ST\TranslateWpmlString;
use WPML\ST\TranslationFile\StringEntity;
use function wpml_collect;
class Generator {
/** @var MOFactory */
private $moFactory;
public function __construct( MOFactory $moFactory ) {
$this->moFactory = $moFactory;
}
/**
* @param StringEntity[] $entries
*
* @return string
*/
public function getContent( array $entries ) {
$mo = $this->moFactory->createNewInstance();
wpml_collect( $entries )
->reduce( [ $this, 'createMOFormatEntities' ], wpml_collect( [] ) )
->filter( function( array $entry ) { return ! empty($entry['singular']); } )
->each( [ $mo, 'add_entry' ] );
$mem_file = fopen( 'php://memory', 'r+' );
$mo->export_to_file_handle( $mem_file );
rewind( $mem_file );
$mo_content = stream_get_contents( $mem_file );
fclose( $mem_file );
return $mo_content;
}
/**
* @param Collection $carry
* @param StringEntity $entry
*
* @return Collection
*/
public function createMOFormatEntities( $carry, StringEntity $entry ) {
$carry->push( $this->mapStringEntityToMOFormatUsing( $entry, 'original' ) );
if ( TranslateWpmlString::canTranslateWithMO( $entry->get_original(), $entry->get_name() ) ) {
$carry->push( $this->mapStringEntityToMOFormatUsing( $entry, 'name' ) );
}
return $carry;
}
/**
* @param StringEntity $entry
* @param string $singularField
*
* @return array
*/
private function mapStringEntityToMOFormatUsing( StringEntity $entry, $singularField ) {
return [
'singular' => $entry->{'get_' . $singularField}(),
'translations' => $entry->get_translations(),
'context' => $entry->get_context(),
'plural' => $entry->get_original_plural(),
];
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace WPML\ST\MO\File;
class MOFactory {
/**
* @return \MO
*/
public function createNewInstance() {
return new \MO();
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace WPML\ST\MO\File;
use GlobIterator;
use WPML\Collect\Support\Collection;
use WPML\ST\TranslationFile\Domains;
use WPML\ST\TranslationFile\StringsRetrieve;
use WPML_Language_Records;
class Manager extends \WPML\ST\TranslationFile\Manager {
public function __construct(
StringsRetrieve $strings,
Builder $builder,
\WP_Filesystem_Direct $filesystem,
WPML_Language_Records $language_records,
Domains $domains
) {
parent::__construct( $strings, $builder, $filesystem, $language_records, $domains );
}
/**
* @return string
*/
protected function getFileExtension() {
return 'mo';
}
/**
* @return bool
*/
public function isPartialFile() {
return true;
}
/**
* @return Collection
*/
protected function getDomains() {
return $this->domains->getMODomains();
}
/**
* @return bool
*/
public static function hasFiles() {
return (bool) ( new GlobIterator( self::getSubdir() . '/*.mo' ) )->count();
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace WPML\ST\MO\File;
use function WPML\Container\make;
class ManagerFactory {
/**
* @return Manager
* @throws \WPML\Auryn\InjectionException
*/
public static function create() {
return make( Manager::class, [ ':builder' => make( Builder::class ) ] );
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace WPML\ST\MO\File;
trait makeDir {
/**
* @var \WP_Filesystem_Direct
*/
protected $filesystem;
/** @return bool */
public function maybeCreateSubdir() {
$subdir = $this->getSubdir();
if ( $this->filesystem->is_dir( $subdir ) && $this->filesystem->is_writable( $subdir ) ) {
return true;
}
return $this->filesystem->mkdir( $subdir, 0755 & ~ umask() );
}
/**
* This declaration throws a "Strict standards" warning in PHP 5.6.
* @todo: Remove the comment when we drop support for PHP 5.6.
*/
//abstract public static function getSubdir();
}