Files
conservatorio-tomadini/libraries/allediaframework/Framework/Base.php
2024-12-17 17:34:10 +01:00

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();
}
}