File: //proc/1526/cwd/azvo/wp-content/plugins/sitepress-multilingual-cms/vendor/wpml/fp/core/Obj.php
<?php
namespace WPML\FP;
use WPML\Collect\Support\Collection;
use WPML\Collect\Support\Traits\Macroable;
use WPML\FP\Functor\ConstFunctor;
use WPML\FP\Functor\IdentityFunctor;
/**
* @method static callable|mixed prop( ...$key, ...$obj ) - Curried :: string->Collection|array|object->mixed|null
* @method static callable|mixed propOr( ...$default, ...$key, ...$obj ) - Curried :: mixed->string->Collection|array|object->mixed|null
* @method static callable|array props( ...$keys, ...$obj ) - Curried :: [keys] → Collection|array|object → [v]
* @method static callable|array|\stdClass addProp( ...$key, ...$transformation, ...$obj ) - Curried :: string->callable->object|array->object->array
* @method static callable|array|\stdClass removeProp( ...$key, ...$obj ) - Curried :: string->object|array->object->array
* @method static callable|array|\stdClass renameProp( ...$key, ...$newKey, ...$obj ) - Curried :: string->string->object|array->object->array
* @method static callable|mixed path( ...$path, ...$obj ) - Curried :: array->Collection|array|object->mixed|null
* @method static callable|mixed pathOr( ...$default, ...$path, ...$obj ) - Curried :: mixed → array → Collection|array|object → mixed
* @method static callable assoc( ...$key, ...$value, ...$item ) - Curried :: string->mixed->Collection|array|object->mixed|null
* @method static callable assocPath( ...$path, ...$value, ...$item ) - Curried :: array->mixed->Collection|array|object->mixed|null
* @method static callable lens( ...$getter, ...$setter ) - Curried :: callable->callable->callable
* @method static callable lensProp( ...$prop ) - Curried :: string->callable
* @method static callable lensPath( ...$path ) - Curried :: array->callable
* @method static callable lensMapped( ...$toFunctorFn ) - Curried :: callable->callable
* @method static callable lensMappedProp( ...$prop ) - Curried :: string->callable
* @method static callable view( ...$lens, ...$obj ) - Curried :: callable->Collection|array|object->mixed
* @method static callable set( ...$lens, ...$value, ...$obj ) - Curried :: callable->mixed->Collection|array|object->mixed
* @method static callable over( ...$lens, ...$transformation, ...$obj ) - Curried :: callable->callable->Collection|array|object->mixed
* @method static callable pick( ...$props, ...$obj ) - Curried :: array->Collection|array->Collection|array
* @method static callable pickAll( ...$props, ...$obj ) - Curried :: array->Collection|array->Collection|array
* @method static callable pickBy( ...$predicate, ...$obj ) - Curried :: ( ( v, k ) → bool ) → Collection|array->Collection|array
* @method static callable pickByKey( ...$predicate, ...$obj ) - Curried :: ( ( k ) → bool ) → Collection|array->callable|Collection|array|object
* @method static callable project( ...$props, ...$target ) - Curried :: array->Collection|array->Collection|array
* @method static callable where( array $condition ) - Curried :: [string → ( * → bool )] → bool
* @method static callable|bool has( ...$prop, ...$item ) - Curried :: string → a → bool
* @method static callable|bool hasPath( ...$path, ...$item ) - Curried :: array<string> → a → bool
* @method static callable|mixed evolve( ...$transformations, ...$item ) - Curried :: array → array → array
*
* @method static callable|array objOf( ...$key, ...$value ) - Curried :: string->mixed->array
*
* Creates an object containing a single key:value pair.
*
* @method static callable|array keys( ...$obj ) - Curried :: object|array->array
*
* Returns
* - keys if argument is an array
* - public properties' names if argument is an object
* - keys if argument is Collection
*
* ```
* $this->assertEquals( [ 0, 1, 2 ], Obj::keys( [ 'a', 'b', 'c' ] ) );
* $this->assertEquals( [ 'a', 'b', 'c' ], Obj::keys( [ 'a' => 1, 'b' => 2, 'c' => 3 ] ) );
*
* $this->assertEquals( [ 0, 1, 2 ], Obj::keys( \wpml_collect( [ 'a', 'b', 'c' ] ) ) );
* $this->assertEquals( [ 'a', 'b', 'c' ], Obj::keys( \wpml_collect( [ 'a' => 1, 'b' => 2, 'c' => 3 ] ) ) );
*
* $this->assertEquals( [ 'a', 'b', 'c' ], Obj::keys( (object) [ 'a' => 1, 'b' => 2, 'c' => 3 ] ) );
* ```
*
* @method static callable|array values( ...$obj ) - Curried :: object|array->array
*
* Returns
* - values if argument is an array
* - public properties' values if argument is an object
* - values if argument is Collection
*
* ```
* $this->assertEquals( [ 'a', 'b', 'c' ], Obj::values( [ 'a', 'b', 'c' ] ) );
* $this->assertEquals( [ 1, 2, 3 ], Obj::values( [ 'a' => 1, 'b' => 2, 'c' => 3 ] ) );
*
* $this->assertEquals( [ 'a', 'b', 'c' ], Obj::values( \wpml_collect( [ 'a', 'b', 'c' ] ) ) );
* $this->assertEquals( [ 1, 2, 3 ], Obj::values( \wpml_collect( [ 'a' => 1, 'b' => 2, 'c' => 3 ] ) ) );
*
* $this->assertEquals( [ 1, 2, 3 ], Obj::values( (object) [ 'a' => 1, 'b' => 2, 'c' => 3 ] ) );
* ```
*
* @method static callable|array replaceRecursive( array ...$newValue, ...$target ) - Curried :: array->array->array
*
* @method static callable|array toArray( Collection|Object ...$item ) - Curried :: Collection|Object->array
*/
class Obj {
use Macroable;
/**
* @return void
*/
public static function init() {
self::macro( 'prop', curryN( 2, function ( $key, $item ) {
return self::propOr( null, $key, $item );
} ) );
self::macro( 'propOr', curryN( 3, function ( $default, $key, $item ) {
if ( $item instanceof Collection ) {
return $item->get( $key, $default );
}
if ( is_array( $item ) ) {
return array_key_exists( $key, $item ) ? $item[ $key ] : $default;
}
if ( is_object( $item ) ) {
if ( property_exists( $item, $key ) || isset( $item->$key ) ) {
return $item->$key;
} elseif ( is_numeric( $key ) ) {
return self::propOr( $default, $key, (array) $item );
} else {
return $default;
}
}
if ( is_null( $item ) ) {
return null;
}
throw( new \InvalidArgumentException( 'item should be a Collection or an array or an object' ) );
} ) );
self::macro( 'props', curryN( 2, function ( array $keys, $item ) {
return Fns::map( Obj::prop( Fns::__, $item ), $keys );
} ) );
self::macro( 'addProp', curryN( 3, function ( $key, $transformation, $data ) {
return Obj::assoc( $key, $transformation( $data ), $data );
} ) );
self::macro( 'removeProp', curryN( 2, function ( $key, $data ) {
if ( is_array( $data ) ) {
unset( $data[ $key ] );
return $data;
} elseif ( is_object( $data ) ) {
$newData = clone $data;
unset( $newData->$key );
return $newData;
}
return $data;
} ) );
self::macro( 'renameProp', curryN( 3, function ( $key, $newKey, $data ) {
$data = self::addProp( $newKey, self::prop( $key ), $data );
return self::removeProp( $key, $data );
} ) );
self::macro( 'path', curryN( 2, function ( $path, $item ) {
return array_reduce( $path, flip( self::prop() ), $item );
} ) );
self::macro( 'pathOr', curryN( 3, function ( $default, $path, $item ) {
$result = Either::of( $item )
->tryCatch( Obj::path( $path ) )
->getOrElse( null );
return is_null( $result ) ? $default : $result;
} ) );
self::macro( 'assocPath', curryN( 3, function ( $path, $val, $item ) {
$split = [ $item ];
for ( $i = 0; $i < count( $path ) - 1; $i ++ ) {
$split[] = self::prop( $path[ $i ], $split[ $i ] );
}
$split = array_reverse( $split );
$reversePath = array_reverse( $path );
$split[0] = self::assoc( $reversePath[0], $val, $split[0] );
for ( $i = 1; $i < count( $reversePath ); $i ++ ) {
$key = $reversePath[ $i ];
$split[ $i ] = self::assoc( $key, $split[ $i - 1 ], $split[ $i ] );
}
return array_pop( $split );
} ) );
self::macro( 'assoc', curryN( 3, function ( $key, $value, $item ) {
if ( $item instanceof Collection ) {
$item = clone $item;
return $item->put( $key, $value );
}
if ( is_array( $item ) ) {
$item[ $key ] = $value;
return $item;
}
if ( is_object( $item ) ) {
$item = clone $item;
$item->$key = $value;
return $item;
}
if ( is_null( $item ) ) {
return null;
}
throw( new \InvalidArgumentException( 'item should be a Collection or an array or an object' ) );
} ) );
self::macro( 'lens', curryN( 2, function ( $getter, $setter ) {
return function ( $toFunctorFn ) use ( $getter, $setter ) {
return function ( $target ) use ( $toFunctorFn, $getter, $setter ) {
$result = $getter( $target );
return Fns::map( function ( $focus ) use ( $setter, $target ) {
return $setter( $focus, $target );
}, $toFunctorFn( $result ) );
};
};
} ) );
self::macro( 'lensProp', curryN( 1, function ( $prop ) {
return self::lens( self::prop( $prop ), self::assoc( $prop ) );
} ) );
self::macro( 'lensPath', curryN( 1, function ( $path ) {
return self::lens( self::path( $path ), self::assocPath( $path ) );
} ) );
self::macro( 'lensMapped', curryN( 1, function ( $toFunctorFn ) {
return function ( $target ) use ( $toFunctorFn ) {
return IdentityFunctor::of(
Logic::isMappable( $target )
? Fns::map( pipe( $toFunctorFn, invoke( 'get' ) ), $target )
: $target
);
};
} ) );
self::macro( 'lensMappedProp', curryN( 1, function ( $prop ) {
return compose( Obj::lensProp( $prop ), Obj::lensMapped() );
} ) );
self::macro( 'view', curryN( 2, function ( $lens, $obj ) {
$view = $lens( [ ConstFunctor::class, 'of' ] );
return $view( $obj )->get();
} ) );
self::macro( 'set', curryN( 3, function ( $lens, $value, $obj ) {
return self::over( $lens, Fns::always( $value ), $obj );
} ) );
self::macro( 'over', curryN( 3, function ( $lens, $transformation, $obj ) {
$over = $lens( function ( $value ) use ( $transformation ) {
return IdentityFunctor::of( $transformation( $value ) );
} );
return $over( $obj )->get();
} ) );
self::macro( 'pick', curryN( 2, function ( array $props, $item ) {
$find = curryN( 3, function ( $item, $result, $prop ) {
$value = self::propOr( new Undefined(), $prop, $item );
if ( ! $value instanceof Undefined ) {
$result[ $prop ] = $value;
}
return $result;
} );
$result = Fns::reduce( $find( $item ), [], $props );
return self::matchType( $result, $item );
} ) );
self::macro( 'pickAll', curryN( 2, function ( array $props, $item ) {
$find = curryN( 3, function ( $item, $result, $prop ) {
$result[ $prop ] = self::prop( $prop, $item );
return $result;
} );
$result = Fns::reduce( $find( $item ), [], $props );
return self::matchType( $result, $item );
} ) );
self::macro( 'project', curryN( 2, function ( array $props, $items ) {
return Fns::map( Obj::pick( $props ), $items );
} ) );
self::macro( 'where', curryN( 2, function ( array $conditions, $items ) {
foreach ( $conditions as $prop => $condition ) {
$filter = pipe( Obj::prop( $prop ), Logic::both( Logic::isNotNull(), $condition ) );
$items = Fns::filter( $filter, $items );
}
return $items;
} ) );
self::macro( 'pickBy', curryN( 2, function ( callable $predicate, $item ) {
$result = array_filter( self::toArray( $item ), $predicate, ARRAY_FILTER_USE_BOTH );
return self::matchType( $result, $item );
} ) );
self::macro( 'pickByKey', curryN( 2, function ( callable $predicate, $item ) {
return self::pickBy( pipe( Fns::nthArg( 1 ), $predicate ), $item );
} ) );
self::macro( 'hasPath', curryN( 2, function ( $path, $item ) {
$undefinedValue = new Undefined();
$currentElement = $item;
foreach ( $path as $pathProp ) {
$currentElement = Either::of( $currentElement )
->tryCatch( self::propOr( $undefinedValue, $pathProp ) )
->getOrElse( $undefinedValue );
if ( $undefinedValue === $currentElement ) {
return false;
}
}
return true;
} ) );
self::macro( 'has', curryN( 2, function ( $prop, $item ) {
if ( $item instanceof Collection ) {
return $item->has( $prop );
}
if ( is_array( $item ) ) {
return isset( $item[ $prop ] );
}
if ( is_object( $item ) ) {
return property_exists( $item, $prop );
}
throw( new \InvalidArgumentException( 'item should be a Collection or an array or an object' ) );
} ) );
self::macro( 'evolve', curryN( 2, function ( $transformations, $item ) {
$temp = self::toArray( $item );
foreach ( $transformations as $prop => $transformation ) {
if ( isset( $temp[ $prop ] ) ) {
if ( is_callable( $transformation ) ) {
$temp[ $prop ] = $transformation( $temp[ $prop ] );
} elseif ( is_array( $transformation ) ) {
$temp[ $prop ] = self::evolve( $transformation, $temp[ $prop ] );
}
}
}
return self::matchType( $temp, $item );
} ) );
self::macro( 'keys', curryN( 1, function ( $obj ) {
if ( is_array( $obj ) ) {
return array_keys( $obj );
} elseif ( $obj instanceof Collection ) {
return $obj->keys()->toArray();
} elseif ( is_object( $obj ) ) {
return array_keys( get_object_vars( $obj ) );
}
throw new \InvalidArgumentException( 'obj should be either array or object' );
} ) );
self::macro( 'values', curryN( 1, function ( $obj ) {
if ( is_array( $obj ) ) {
return array_values( $obj );
} elseif ( $obj instanceof Collection ) {
return $obj->values()->toArray();
} elseif ( is_object( $obj ) ) {
return array_values( get_object_vars( $obj ) );
}
throw new \InvalidArgumentException( 'obj should be either array or object' );
} ) );
self::macro( 'objOf', curryN( 2, function ( $key, $value ) {
return [ $key => $value ];
} ) );
self::macro( 'replaceRecursive', curryN( 2, flip( 'array_replace_recursive' ) ) );
self::macro( 'toArray', curryN( 1, function ( $item ) {
$temp = $item;
if ( $temp instanceof Collection ) {
$temp = $temp->toArray();
}
if ( is_object( $temp ) ) {
$temp = (array) $temp;
}
return $temp;
} ) );
}
/**
* @param object|Collection $item
* @param object|Collection $reference
*
* @return object|Collection
*/
private static function matchType( $item, $reference ) {
if ( $reference instanceof Collection ) {
return wpml_collect( $item );
}
if ( is_object( $reference ) ) {
return (object) $item;
}
return $item;
}
/**
* Curried :: mixed → array|object|Collection → array|object|Collection
* function to remove an item by key from an array.
*
* @param string|int $key
* @param array|object|Collection|null $item
*
* @return callable|array|object|Collection
*/
static function without( $key = null, $item = null ) {
$without = function ( $key, $item ) {
$temp = self::toArray( $item );
unset( $temp[ $key ] );
return self::matchType( $temp, $item );
};
return call_user_func_array( curryN( 2, $without ), func_get_args() );
}
/**
* Curried :: array|object -> array|object -> array|object
*
* It merges the new data with item.
*
* @param array|object $newData
* @param array|object $item
*
* @return array|object
*/
public static function merge( $newData = null, $item = null ) {
$merge = function ( $newData, $item ) {
$isNested = Logic::anyPass( [ 'is_array', 'is_object' ] );
foreach ( (array) $newData as $key => $value ) {
if ( $isNested( $newData ) && Obj::has( $key, $item ) && $isNested( Obj::prop( $key, $item ) ) ) {
$item = Obj::assoc( $key, self::merge( $value, Obj::prop( $key, $item ) ), $item );
} else {
$item = Obj::assoc( $key, $value, $item );
}
}
return $item;
};
return call_user_func_array( curryN( 2, $merge ), func_get_args() );
}
}
Obj::init();