225 lines
6.6 KiB
PHP
225 lines
6.6 KiB
PHP
<?php
|
|
/**
|
|
* @package AllediaFramework
|
|
* @contact www.joomlashack.com, help@joomlashack.com
|
|
* @copyright 2016-2023 Joomlashack.com. All rights reserved
|
|
* @license https://www.gnu.org/licenses/gpl.html GNU/GPL
|
|
*
|
|
* This file is part of AllediaFramework.
|
|
*
|
|
* AllediaFramework is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* AllediaFramework is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with AllediaFramework. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
namespace Alledia\Framework;
|
|
|
|
defined('_JEXEC') or die();
|
|
|
|
class Base
|
|
{
|
|
public const MAP_UNDEFINED = 'undefined';
|
|
|
|
/**
|
|
* Retrieve all public properties and their values
|
|
* Although this duplicates get_object_vars(), it
|
|
* is mostly useful for internal calls when we need
|
|
* to filter out the non-public properties.
|
|
*
|
|
* @param bool $publicOnly
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getProperties($publicOnly = true)
|
|
{
|
|
$reflection = new \ReflectionObject($this);
|
|
$properties = $reflection->getProperties(\ReflectionProperty::IS_PUBLIC);
|
|
if (!$publicOnly) {
|
|
$properties = array_merge(
|
|
$properties,
|
|
$reflection->getProperties(\ReflectionProperty::IS_PROTECTED)
|
|
);
|
|
}
|
|
|
|
$data = [];
|
|
foreach ($properties as $property) {
|
|
$name = $property->name;
|
|
$data[$name] = $this->{$name};
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Set the public properties from the passed array/object
|
|
*
|
|
* @param array|Base $data Values to copy to $this
|
|
* @param ?array $map Use properties from $data translated using a field map
|
|
*
|
|
* @return $this
|
|
* @throws Exception
|
|
*/
|
|
public function setProperties($data, ?array $map = null)
|
|
{
|
|
$properties = $this->getProperties();
|
|
if ($map !== null) {
|
|
$data = $this->map($data, array_keys($properties), $map);
|
|
} elseif (is_object($data)) {
|
|
$data = get_object_vars($data);
|
|
}
|
|
if (!is_array($data)) {
|
|
throw new Exception('Invalid argument given - ' . gettype($data));
|
|
}
|
|
|
|
foreach ($data as $k => $v) {
|
|
if (array_key_exists($k, $properties)) {
|
|
$this->{$k} = $v;
|
|
}
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set all properties to null
|
|
*
|
|
* @param bool $publicOnly Pass false to include protected properties as well
|
|
*
|
|
* @return $this
|
|
*/
|
|
public function clearProperties($publicOnly = true)
|
|
{
|
|
$properties = array_keys($this->getProperties($publicOnly));
|
|
foreach ($properties as $property) {
|
|
$this->{$property} = null;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Map values in a source object/array to Joomlashack Framework keys using a map
|
|
* of key equivalences. Any fields in $keys not present in $map will be
|
|
* mapped name to name. Map fields mapped to null will be ignored.
|
|
*
|
|
* Special mappings for field values are recognized with another array. e.g.:
|
|
*
|
|
* $map['status'] = array(
|
|
* 'state' => array(
|
|
* 'active' => 1,
|
|
* 'closed' => 0,
|
|
* Object::MAP_UNDEFINED => -1
|
|
* )
|
|
* )
|
|
* Will map the extension field 'status' to the source field 'state' and
|
|
* set status based on the value in the state field. If no match, Object::MAP_UNDEFINED
|
|
* will be used for the unknown value.
|
|
*
|
|
*
|
|
* @param array|object $source Source data to be mapped
|
|
* @param array $keys Extension keys for which values are being requested
|
|
* @param array $map Associative array where key=Extension Key, value=Source Key
|
|
*
|
|
* @return array An array of all specified keys with values filled in based on map
|
|
* @throws Exception
|
|
*/
|
|
public function map($source, array $keys, array $map = [])
|
|
{
|
|
if (!is_object($source) && !is_array($source)) {
|
|
throw new Exception('Expected array or object for source argument');
|
|
}
|
|
|
|
$result = array_fill_keys($keys, null);
|
|
foreach ($keys as $srKey) {
|
|
$value = null;
|
|
if (!array_key_exists($srKey, $map)) {
|
|
$field = $srKey;
|
|
$value = $this->getKeyValue($source, $field);
|
|
} else {
|
|
// This is a mapped key
|
|
$field = $map[$srKey];
|
|
|
|
if (!is_array($field)) {
|
|
$value = $this->getKeyValue($source, $field);
|
|
} else {
|
|
// Mapped to field value
|
|
$values = reset($map[$srKey]);
|
|
$field = key($map[$srKey]);
|
|
$srcValue = $this->getKeyValue($source, $field);
|
|
|
|
if (isset($values[$srcValue])) {
|
|
$value = $values[$srcValue];
|
|
} elseif (isset($values[self::MAP_UNDEFINED])) {
|
|
$value = $values[self::MAP_UNDEFINED];
|
|
}
|
|
}
|
|
}
|
|
$result[$srKey] = $value;
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Safely get a value from an object|array
|
|
*
|
|
* @param Base|array $data
|
|
* @param string $var
|
|
* @param mixed $default
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function getKeyValue($data, $var, $default = null)
|
|
{
|
|
if (is_object($data)) {
|
|
return $data->{$var} ?? $default;
|
|
}
|
|
|
|
return $data[$var] ?? $default;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* Default string rendering for the object. Subclasses should feel
|
|
* free to override as desired.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function asString()
|
|
{
|
|
return get_class($this);
|
|
}
|
|
|
|
/**
|
|
* Expose properties with defined getters for direct use
|
|
*
|
|
* @param $name
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function __get($name)
|
|
{
|
|
$method = 'get' . ucfirst($name);
|
|
if (method_exists($this, $method)) {
|
|
return $this->$method();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function __toString()
|
|
{
|
|
return $this->asString();
|
|
}
|
|
}
|