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,33 @@
<?php
namespace WPML\PB\Config;
use WPML\WP\OptionManager;
abstract class Factory implements \IWPML_Backend_Action_Loader, \IWPML_Frontend_Action_Loader {
/**
* @return \IWPML_Action
* @throws \Auryn\InjectionException
*/
public function create() {
return new Hooks(
new Parser(
$this->getPbData( 'configRoot' ),
$this->getPbData( 'defaultConditionKey' )
),
new Storage(
new OptionManager(),
$this->getPbData( 'pbKey' )
),
$this->getPbData( 'translatableWidgetsHook' )
);
}
/**
* @param string $key
*
* @return mixed
*/
abstract protected function getPbData( $key );
}

View File

@@ -0,0 +1,47 @@
<?php
namespace WPML\PB\Config;
use function WPML\FP\tap as tap;
class Hooks implements \IWPML_Action {
const PRIORITY_AFTER_DEFAULT = 20;
/** @var Parser $parser */
private $parser;
/** @var Storage $storage */
private $storage;
/** @var string $translatableWidgetsHook */
private $translatableWidgetsHook;
public function __construct(
Parser $parser,
Storage $storage,
$translatableWidgetsHook
) {
$this->parser = $parser;
$this->storage = $storage;
$this->translatableWidgetsHook = $translatableWidgetsHook;
}
public function add_hooks() {
add_filter( 'wpml_config_array', tap( [ $this, 'extractConfig' ] ) );
add_filter( $this->translatableWidgetsHook , [ $this, 'extendTranslatableWidgets' ], self::PRIORITY_AFTER_DEFAULT );
}
public function extractConfig( array $allConfig ) {
$this->storage->update( $this->parser->extract( $allConfig ) );
}
/**
* @param array $widgets
*
* @return array
*/
public function extendTranslatableWidgets( array $widgets ) {
return array_merge( $widgets, $this->storage->get() );
}
}

View File

@@ -0,0 +1,142 @@
<?php
namespace WPML\PB\Config;
use WPML\FP\Fns;
use WPML\FP\Lst;
use WPML\FP\Maybe;
use WPML\FP\Obj;
class Parser {
/** @var string $configRoot */
private $configRoot;
/** @var string $defaultConditionKey */
private $defaultConditionKey;
public function __construct( $configRoot, $defaultConditionKey ) {
$this->configRoot = $configRoot;
$this->defaultConditionKey = $defaultConditionKey;
}
/**
* Receives a raw config array (from XML) and convert it into
* a page builder configuration array.
*
* @see WPML_Elementor_Translatable_Nodes::get_nodes_to_translate()
*
* @param array $allConfig
*
* @return array
*/
public function extract( array $allConfig ) {
$pbConfig = [];
$allWidgets = Obj::pathOr( [], [ 'wpml-config', $this->configRoot, 'widget' ], $allConfig );
foreach ( $allWidgets as $widget ) {
$widgetName = Obj::path( ['attr', 'name'], $widget );
$pbConfig[ $widgetName ] = [
'conditions' => $this->parseConditions( $widget, $widgetName ),
'fields' => $this->parseFields( Obj::pathOr( [], ['fields', 'field'], $widget ) ),
];
$fieldsInItems = Obj::prop( 'fields-in-item', $widget );
if ( $fieldsInItems ) {
$pbConfig[ $widgetName ]['fields_in_item'] = [];
$fieldsInItems = $this->normalize( $fieldsInItems );
foreach ( $fieldsInItems as $fieldsInItem ) {
$itemOf = Obj::path( [ 'attr', 'items_of' ], $fieldsInItem );
$pbConfig[ $widgetName ]['fields_in_item'][ $itemOf ] = $this->parseFields( Obj::propOr( [], 'field', $fieldsInItem ) );
}
}
$integrationClasses = $this->parseIntegrationClasses( $widget );
if ( $integrationClasses ) {
$pbConfig[ $widgetName ]['integration-class'] = $integrationClasses;
}
}
return $pbConfig;
}
/**
* @param array $widget
* @param string $widgetName
*
* @return array
*/
private function parseConditions( array $widget, $widgetName ) {
$makePair = function( $condition ) {
return [ Obj::pathOr( $this->defaultConditionKey, ['attr', 'key'], $condition ), $condition['value'] ];
};
return Maybe::fromNullable( Obj::path( ['conditions', 'condition'], $widget ) )
->map( [ $this, 'normalize' ] )
->map( Fns::map( $makePair ) )
->map( Lst::fromPairs() )
->getOrElse( [ $this->defaultConditionKey => $widgetName ] );
}
/**
* @param array $rawFields
*
* @return array
*/
private function parseFields( array $rawFields ) {
$parsedFields = [];
foreach ( $this->normalize( $rawFields ) as $field ) {
$key = Obj::path( [ 'attr', 'key_of' ], $field );
$fieldId = Obj::path( [ 'attr', 'field_id' ], $field );
$parsedField = [
'field' => $field['value'],
'type' => Obj::pathOr( $field['value'], [ 'attr', 'type' ], $field ),
'editor_type' => Obj::pathOr( 'LINE', [ 'attr', 'editor_type' ], $field ),
];
if ( $fieldId ) {
$parsedField['field_id'] = $fieldId;
}
if ( $key ) {
$parsedFields[ $key ] = $parsedField;
} else {
$parsedFields[] = $parsedField;
}
}
return $parsedFields;
}
/**
* @param array $widget
*
* @return array
*/
private function parseIntegrationClasses( array $widget ) {
return Maybe::fromNullable( Obj::path( [ 'integration-classes', 'integration-class' ], $widget ) )
->map( [ $this, 'normalize' ] )
->map( Lst::pluck( 'value' ) )
->getOrElse( [] );
}
/**
* If a sequence has only one element, we will wrap it
* in order to have the same data shape as for multiple elements.
*
* @param array $partialConfig
*
* @return array
*/
public function normalize( array $partialConfig ) {
$isAssocArray = count( array_filter( array_keys( $partialConfig ), 'is_string' ) ) > 0;
return $isAssocArray ? [ $partialConfig ] : $partialConfig;
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace WPML\PB\Config;
use WPML\WP\OptionManager;
class Storage {
const OPTION_GROUP = 'api-pb-config';
/** @var OptionManager $optionManager */
private $optionManager;
/** @var string $pbKey */
private $pbKey;
public function __construct(
OptionManager $optionManager,
$pbKey
) {
$this->optionManager = $optionManager;
$this->pbKey = $pbKey;
}
public function get() {
return $this->optionManager->get( self::OPTION_GROUP, $this->pbKey, [] );
}
public function update( array $pbConfig ) {
$this->optionManager->set( self::OPTION_GROUP, $this->pbKey, $pbConfig, false );
}
}