migrate away from logic in PHP in favor of logic on OMS

This commit is contained in:
Michael Becker 2024-11-07 07:34:56 -05:00
parent 6d875abbeb
commit bd367d7ba8
40 changed files with 1738 additions and 1045 deletions

View File

@ -43,13 +43,13 @@ function requiresLogin($path)
System::$BeforeLaunchEventHandler = function($path)
{
/**
* @var \Mocha\Oms\MySQLDatabaseOms
*/
$oms = mocha_get_oms();
if (count($path) >= 1)
{
if ($path[0] == "madi")
if ($path[0] == "themes")
{
return true;
}
else if ($path[0] == "madi")
{
return true;
}
@ -79,6 +79,7 @@ System::$BeforeLaunchEventHandler = function($path)
return false;
}
$oms = mocha_get_oms();
if ($path[0] == "madi")
{
$currentTenantName = $path[2];

View File

@ -2,10 +2,12 @@
use Mocha\Core\InstanceReference;
use Mocha\Core\KnownAttributeGuids;
use Mocha\Core\KnownClassGuids;
use Mocha\Core\KnownInstanceGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\MySQLDatabaseOms;
use Mocha\Core\Oms;
use Mocha\UI\Renderers\HTML\HTMLRenderer;
use Phast\System;
@ -17,7 +19,18 @@ function mocha_asset_exists($package, $version, $path)
{
return file_exists(mocha_asset_get_physical_path($package, $version, $path));
}
function mocha_get_oms()
function mocha_print_unavailable_message()
{
$ctx = new OmsContext();
$html = new HTMLRenderer($ctx, true);
$html->IncludeTopNavigationBar = false;
$html->renderBeginErrorPage("Mocha is currrently unavailable", "We are experiencing a service interruption");
echo ("<p>Your service will be restored as quickly as possible.</p>");
echo ("<p>We apologize for the inconvenience. If you are a MochaPowered customer and require additional assistance please contact the Designated Support Contact within your organization. Otherwise, please check back later.</p>");
$html->renderEndErrorPage();
die();
}
function mocha_get_oms() : Oms|null
{
/*
if (!isset($_SESSION["OMS"]))
@ -35,23 +48,22 @@ function mocha_get_oms()
{
try
{
$oms = new MySQLDatabaseOms(System::GetConfigurationValue("Database.ServerName"), System::GetConfigurationValue("Database.PortNumber"), System::GetConfigurationValue("Database.DatabaseName"), System::GetConfigurationValue("Database.UserName"), System::GetConfigurationValue("Database.Password"));
// $oms = new \Mocha\Oms\MySQLDatabaseOms(System::GetConfigurationValue("Database.ServerName"), System::GetConfigurationValue("Database.PortNumber"), System::GetConfigurationValue("Database.DatabaseName"), System::GetConfigurationValue("Database.UserName"), System::GetConfigurationValue("Database.Password"));
$oms = new \Mocha\Oms\HttpOmsClient("localhost", 4436);
}
catch (\PDOException $ex)
{
if (file_exists("setup.php"))
{
System::Redirect("~/setup", true);
return $oms;
return null;
}
$ctx = new OmsContext();
$html = new HTMLRenderer($ctx, true);
$html->IncludeTopNavigationBar = false;
$html->renderBeginErrorPage("Mocha is currrently unavailable", "We are experiencing a service interruption");
echo ("<p>Your service will be restored as quickly as possible.</p>");
echo ("<p>We apologize for the inconvenience. If you are a MochaPowered customer and require additional assistance please contact the Designated Support Contact within your organization. Otherwise, please check back later.</p>");
$html->renderEndErrorPage();
die();
mocha_print_unavailable_message();
}
if (!$oms->isConnected())
{
mocha_print_unavailable_message();
}
}
$oms->setCurrentUser(mocha_get_current_user());
@ -60,27 +72,47 @@ function mocha_get_oms()
function mocha_get_current_user() : ?InstanceReference
{
/**
* @var MySQLDatabaseOms
* @var Oms
*/
global $oms; //! WE CANNOT CALL mocha_get_oms() HERE!
if ($oms === null)
{
echo ("mocha_oms is null"); die();
return null;
}
$currentTenant = $oms->getTenant();
if ($currentTenant == null)
{
$path = System::GetVirtualPath(false);
if ($path[0] == "madi")
{
if ($path[1] == "authgwy")
{
$currentTenant = $oms->getTenantByName($path[2]);
}
}
else
{
$currentTenant = $oms->getTenantByName($path[0]);
}
$oms->setTenant($currentTenant);
}
if ($currentTenant !== null)
{
if (isset($_SESSION["user_token_" . $currentTenant->ID]))
{
// SELECT FROM `Users` WHERE `Token` = $_SESSION["user_token"]
$insts = $oms->getInstancesByAttributes(array
$insts = $oms->getInstancesOfByAttributes(KnownClassGuids::UserLogin, array
(
KnownAttributeGuids::Token => $_SESSION["user_token_" . $currentTenant->ID]
));
$currentUser = null;
$loginEntry = null;
// echo ("count(insts) = " . count($insts)); die();
if (count($insts) == 1)
{
$loginEntry = $insts[0];
@ -102,6 +134,14 @@ function mocha_get_current_user() : ?InstanceReference
return $currentUser;
}
}
else
{
// echo ("user_token is NOT set"); die();
}
}
else
{
echo ("currentTenant is null"); die();
}
return null;
}

View File

@ -29,7 +29,7 @@
}
public static function TryParse(?string $instanceKeyStr, ?InstanceKey &$out) : bool
{
$ik = InstanceKey::Parse($instanceKeyStr);
$ik = InstanceKey::parse($instanceKeyStr);
if ($ik !== null)
{
$out = $ik;

View File

@ -1,7 +1,7 @@
<?php
namespace Mocha\Core;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Oop\Method;
use Mocha\Oop\MethodBinding;
@ -11,9 +11,9 @@
class InstanceReference
{
//public Oms $OMS;
public int $DatabaseId;
public InstanceKey $InstanceKey;
public UUID $GlobalIdentifier;
public ?int $DatabaseId;
public InstanceKey|null $InstanceKey;
public UUID|null $GlobalIdentifier;
public static function toInstanceKeys(array $instanceReferences) : array
{
@ -25,7 +25,7 @@
return $keys;
}
public function __construct(int $databaseId, InstanceKey $instanceKey, UUID|string $globalIdentifier)
public function __construct(?int $databaseId, InstanceKey|null $instanceKey, UUID|string|null $globalIdentifier)
{
//$this->OMS = $oms;
$this->DatabaseId = $databaseId;
@ -33,7 +33,7 @@
if (is_string($globalIdentifier))
{
$globalIdentifier = UUID::Parse($globalIdentifier);
$globalIdentifier = UUID::parse($globalIdentifier);
}
$this->GlobalIdentifier = $globalIdentifier;
}

View File

@ -1,8 +1,972 @@
<?php
namespace Mocha\Core;
class Oms
{
use Mocha\Core\InstanceKey;
use Mocha\Core\InstanceReference;
use Mocha\Core\KnownClassGuids;
use Mocha\Core\KnownInstanceGuids;
use Mocha\Core\KnownAttributeGuids;
use Mocha\Core\KnownMethodBindingGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Core\TenantReference;
use Mocha\Oop\MethodImplementation;
use Mocha\Oop\Methods\BuildAttributeMethod;
use Phast\System;
use Phast\Utilities\Stopwatch;
use Phast\UUID;
abstract class Oms
{
public ?array $MethodImplementations;
public function __construct()
{
$this->_tenant = null;
$this->_pclass_cache = null;
$this->MetadataExceptions = array();
$this->MethodImplementations = null;
}
public function getUserByUserName(string $username) : ?InstanceReference
{
$users = $this->getInstancesOf(KnownClassGuids::User);
foreach ($users as $user)
{
$actualUsername = $this->getAttributeValue($user, KnownAttributeGuids::UserName);
if ($username == $actualUsername)
{
return $user;
}
}
return null;
}
private function registerMethodImplementation(InstanceReference|string|InstanceKey $methodImplementationClass, MethodImplementation $implementation)
{
$methodImplementationClass = $this->normalizeInstanceReference($methodImplementationClass);
$this->MethodImplementations[$methodImplementationClass->GlobalIdentifier->__toString()] = $implementation;
}
private function initializeMethodImplementations()
{
$this->registerMethodImplementation(KnownClassGuids::BuildAttributeMethod, new \Mocha\Oop\MethodImplementations\BuildAttributeMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::ConditionalSelectAttributeMethod, new \Mocha\Oop\MethodImplementations\ConditionalSelectAttributeMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::ConditionalSelectFromInstanceSetMethod, new \Mocha\Oop\MethodImplementations\ConditionalSelectInstanceSetMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::EvaluateBooleanExpressionMethod, new \Mocha\Oop\MethodImplementations\EvaluateBooleanExpressionMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::GetAttributeBySystemRoutineMethod, new \Mocha\Oop\MethodImplementations\GetAttributeBySystemRoutineMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::GetAttributeMethod, new \Mocha\Oop\MethodImplementations\GetAttributeMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::GetInstanceSetBySystemRoutineMethod, new \Mocha\Oop\MethodImplementations\GetInstanceSetBySystemRoutineMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::GetInstancesMethod, new \Mocha\Oop\MethodImplementations\GetInstancesMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::GetReferencedAttributeMethod, new \Mocha\Oop\MethodImplementations\GetReferencedAttributeMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::GetReferencedInstanceSetMethod, new \Mocha\Oop\MethodImplementations\GetReferencedInstanceSetMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::GetSpecifiedInstancesMethod, new \Mocha\Oop\MethodImplementations\GetSpecifiedInstancesMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::ProcessRelatedUpdatesMethod, new \Mocha\Oop\MethodImplementations\ProcessRelatedUpdatesMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::SelectFromInstanceSetMethod, new \Mocha\Oop\MethodImplementations\SelectFromInstanceSetMethodImplementation());
}
private function getMethodImplementation(InstanceReference|string|InstanceKey $methodImplementationClass)
{
if ($this->MethodImplementations === null)
{
// initialize method implementations
// we cannot do this in the constructor, since it relies on getInstanceByGlobalIdentifier
// which fails if the current tenant is null, and we need OMS to get the current tenant...
$this->initializeMethodImplementations();
}
$methodImplementationClass = $this->normalizeInstanceReference($methodImplementationClass);
$key = $methodImplementationClass->GlobalIdentifier->__toString();
if (array_key_exists($key, $this->MethodImplementations))
{
return $this->MethodImplementations[$key];
}
return null;
}
/**
* @var array
*/
public $MetadataExceptions;
protected function getInstancesInternal() : array
{
return [ ];
}
/**
* Gets ALL instances on this OMS.
*/
public function getInstances() : array
{
return $this->getInstancesInternal();
}
/**
* Gets the instance with the specified global identifier.
*/
public abstract function getInstanceByGlobalIdentifier(UUID|string $inst) : ?InstanceReference;
/**
* Indices are 1-based
*/
public function getNthInstanceOf(InstanceReference|string|InstanceKey $sourceInstance, int $index, $defaultValue = null)
{
$insts = $this->getRelatedInstances($sourceInstance, KnownRelationshipGuids::Class__has__Instance);
if (count($insts) > 0)
{
return $insts[$index - 1];
}
return $defaultValue;
}
public function instanceKeysToInstances(array|string|null $instanceKeys)
{
$insts = [ ];
if ($instanceKeys === null)
{
return $insts;
}
if (is_string($instanceKeys))
{
$instanceKeys = explode(",", $instanceKeys);
}
foreach ($instanceKeys as $instanceKey)
{
if (is_string($instanceKey))
{
$instanceKey = InstanceKey::parse($instanceKey);
}
if ($instanceKey !== null)
{
$insts[] = $this->getInstanceByKey($instanceKey);
}
}
return $insts;
}
public function getRelatedInstances(InstanceReference|string|InstanceKey $sourceInstance, InstanceReference|string|InstanceKey|null $relationshipInstance, \DateTime $effectiveDate = null) : ?array
{
$tenant = $this->getTenant();
if ($tenant === null)
{
trigger_error("tenant cannot be null", \E_USER_ERROR);
return null;
}
$sourceInstance = $this->normalizeInstanceReference($sourceInstance);
$relationshipInstance = $this->normalizeInstanceReference($relationshipInstance);
if ($relationshipInstance === null)
{
//echo ("Relationship Instance is null");
return null;
}
// trigger_error("MADI debug: entering " . get_class($this) . "::getRelatedInstancesInternal");
// $stopwatch = new Stopwatch();
// $stopwatch->start();
$insts = $this->getRelatedInstancesInternal($sourceInstance, $relationshipInstance, $effectiveDate);
// $stopwatch->stop();
// trigger_error("MADI debug: exiting " . get_class($this) . "::getRelatedInstancesInternal (took " . $stopwatch->getElapsedTime() . "s)");
return $insts;
}
protected abstract function getRelatedInstancesInternal(InstanceReference $sourceInstance, InstanceReference $relationshipInstance, \DateTime $effectiveDate = null) : ?array;
public function getRelatedInstance(InstanceReference|string|InstanceKey $sourceInstance, InstanceReference|string|InstanceKey $relationshipInstance, \DateTime $effectiveDate = null) : ?InstanceReference
{
$insts = $this->getRelatedInstances($sourceInstance, $relationshipInstance, $effectiveDate);
if ($insts === null)
return null;
if (count($insts) === 0)
return null;
return $insts[0];
}
/**
* Gets the parent class Instance of the specified Instance.
*/
public function getParentClass(InstanceReference $inst) : ?InstanceReference
{
$gid = $inst->GlobalIdentifier->__toString();
$forClass = $this->getRelatedInstance($inst, $this->getInstanceByGlobalIdentifier(KnownRelationshipGuids::Instance__for__Class));
return $forClass;
}
/**
* Gets the instance representing the default tenant.
*/
public function getTenantInstance() : ?InstanceReference
{
return $this->getInstanceByGlobalIdentifier(KnownInstanceGuids::DefaultTenant);
}
/**
* Gets the value of the given attribute on the specified instance.
*/
public function getAttributeValue(InstanceReference|string|InstanceKey|null $sourceInstance, InstanceReference|string|InstanceKey|null $attributeInstance, $defaultValue = null, $effectiveDate = null) : ?string
{
$tenant = $this->getTenant();
if ($tenant === null)
{
trigger_error("tenant cannot be null", \E_USER_ERROR);
return null;
}
$sourceInstance = $this->normalizeInstanceReference($sourceInstance);
$attributeInstance = $this->normalizeInstanceReference($attributeInstance);
if ($sourceInstance === null || $attributeInstance === null)
return $defaultValue;
return $this->getAttributeValueInternal($sourceInstance, $attributeInstance, $defaultValue, $effectiveDate);
}
protected abstract function getAttributeValueInternal(InstanceReference $sourceInstance, InstanceReference $attributeInstance, $defaultValue = null, $effectiveDate = null) : ?string;
public function setAttributeValue(InstanceReference|string|InstanceKey $sourceInstance, InstanceReference|string|InstanceKey $attributeInstance, mixed $value, ?\DateTime $effectiveDate = null)
{
$tenant = $this->getTenant();
if ($tenant === null)
{
trigger_error("tenant cannot be null", \E_USER_ERROR);
return null;
}
$sourceInstance = $this->normalizeInstanceReference($sourceInstance);
$attributeInstance = $this->normalizeInstanceReference($attributeInstance);
$this->setAttributeValueInternal($sourceInstance, $attributeInstance, $value, $effectiveDate);
}
protected abstract function setAttributeValueInternal(InstanceReference $sourceInstance, InstanceReference $attributeInstance, mixed $value, ?\DateTime $effectiveDate = null);
public function getDefaultTaskUrl(InstanceReference $inst) : ?string
{
$instParent = $this->getParentClass($inst);
if ($instParent === null)
return null;
$instDefaultTask = $this->getRelatedInstance($instParent, KnownRelationshipGuids::Class__has_default__Task);
if ($instDefaultTask != null)
{
// !FIXME: check to see if the task is authorized for the current user
// (e.g. this can be by if `User .has Security Domain` any in `Securable.has Security Domain`)
// e.g. if User has `Administrator` and Task has `Administrator`, return true
if (true) // ($oms->isTaskAuthorizedForUser($instDefaultTask, $oms->getCurrentUser()))
{
return System::ExpandRelativePath("~/d/inst/" . $instParent->InstanceKey . "/" . $inst->InstanceKey . ".htmld");
}
}
return null;
}
private $_instanceTextCache;
public function getInstanceText($inst)
{
if ($inst === null)
return "ERR: inst null";
$data = $this->getInstanceData($inst);
return $data["text"];
/*
if ($this->_instanceTextCache === null)
{
$this->_instanceTextCache = array();
}
if (array_key_exists($inst->GlobalIdentifier->__toString(), $this->_instanceTextCache))
{
return $this->_instanceTextCache[$inst->GlobalIdentifier->__toString()];
}
$parentClass = $this->getParentClass($inst);
if ($parentClass === null)
{
$this->MetadataExceptions[] = new OmsMetadataException("Parent class empty", array
(
"For Instance" => $inst
));
return "ERR: no parent class for inst";
}
$instancesLabeledByRAMB = $this->getRelatedInstance($parentClass, KnownRelationshipGuids::Class__instances_labeled_by__Executable_returning_Attribute);
if ($instancesLabeledByRAMB !== null)
{
$context = new OmsContext();
$context->setWorkData($parentClass->GlobalIdentifier->__toString(), $inst);
$textAttr = $this->execute($context, $instancesLabeledByRAMB);
$text = $context->getWorkData($textAttr);
//$this->printWorkData($context->workData);
$this->_instanceTextCache[$inst->GlobalIdentifier->__toString()] = $text;
return $text;
}
else
{
//echo ("no RAMB");
}
return $this->getAttributeValue($inst, $this->getInstanceByGlobalIdentifier(KnownAttributeGuids::Name));
*/
}
public function removeRelationshipInstances(InstanceReference|string|InstanceKey $sourceInstance, InstanceReference|string|InstanceKey $relationshipInstance)
{
$tenant = $this->getTenant();
if ($tenant === null)
{
trigger_error("tenant cannot be null", \E_USER_ERROR);
return null;
}
$sourceInstance = $this->normalizeInstanceReference($sourceInstance);
$relationshipInstance = $this->normalizeInstanceReference($relationshipInstance);
$targetInstances = $this->getRelatedInstances($sourceInstance, $relationshipInstance);
$this->removeRelationshipInstance($sourceInstance, $relationshipInstance, $targetInstances);
}
protected abstract function removeRelationshipInstanceInternal(InstanceReference|string|InstanceKey $sourceInstance, InstanceReference|string|InstanceKey $relationshipInstance, InstanceReference|string|InstanceKey|array $targetInstances, ?\DateTime $effectiveDate = null);
public function removeRelationshipInstance(InstanceReference|string|InstanceKey $sourceInstance, InstanceReference|string|InstanceKey $relationshipInstance, InstanceReference|string|InstanceKey|array $targetInstances, ?\DateTime $effectiveDate = null)
{
return $this->removeRelationshipInstanceInternal($sourceInstance, $relationshipInstance, $targetInstances, $effectiveDate);
}
public function assignRelationship(InstanceReference|string|InstanceKey $sourceInstance, InstanceReference|string|InstanceKey $relationshipInstance, InstanceReference|string|InstanceKey|array $targetInstances, ?\DateTime $effectiveDate = null)
{
$tenant = $this->getTenant();
if ($tenant === null)
{
trigger_error("tenant cannot be null", \E_USER_ERROR);
return null;
}
$sourceInstance = $this->normalizeInstanceReference($sourceInstance);
$relationshipInstance = $this->normalizeInstanceReference($relationshipInstance);
$targetInstances = $this->normalizeInstanceReference($targetInstances);
return $this->assignRelationshipInternal($sourceInstance, $relationshipInstance, $targetInstances, $effectiveDate);
}
protected abstract function assignRelationshipInternal(InstanceReference $sourceInstance, InstanceReference $relationshipInstance, InstanceReference|array $targetInstances, ?\DateTime $effectiveDate = null);
private $_tenant;
public function getTenant() : ?TenantReference
{
return $this->_tenant;
}
public function setTenant(TenantReference $tenant) : void
{
$oldTenant = $this->_tenant;
$this->_tenant = $tenant;
$this->onTenantChanged($oldTenant, $tenant);
}
public function initializeInstanceCache()
{
}
public function onTenantChanged(?TenantReference $oldTenant, ?TenantReference $newTenant)
{
}
public function getTenantName() : ?string
{
if ($this->_tenant !== null)
{
return $this->_tenant->Name;
}
return null;
}
/**
* Gets the tenant with the specified name, or NULl if no tenant with the specified name exists on the server.
*
* @param string $tenantName the name of the desired tenant
*
* @return ?TenantReference
*/
public function getTenantByName(string $tenantName) : ?TenantReference
{
return null;
}
public function getInstanceKeysString(array $instanceReferences, string $separator = ":")
{
$val = "";
$ct = count($instanceReferences);
for($i = 0; $i < $ct; $i++)
{
$val .= $instanceReferences[$i]->InstanceKey;
if ($i < $ct - 1)
{
$val .= $separator;
}
}
return $val;
}
public function printInstanceKeys(array $instanceReferences, string $separator = ":")
{
echo ($this->getInstanceKeysString($instanceReferences, $separator));
}
public function instanceSetContains(array /*<InstanceReference>*/ $haystack, InstanceReference|string|InstanceKey|UUID $needle)
{
$needle = $this->normalizeInstanceReference($needle);
foreach ($haystack as $v)
{
if ($v->GlobalIdentifier == $needle->GlobalIdentifier)
{
return true;
}
}
return false;
}
public function getInstancesOf(InstanceReference|string|InstanceKey|UUID $classInstance) : ?array
{
$classInstance = $this->normalizeInstanceReference($classInstance);
$instances = $this->getRelatedInstances($classInstance, KnownRelationshipGuids::Class__has__Instance);
return $instances;
}
/**
* Given an InstanceReference, GUID (string), or InstanceKey, return the normalized InstanceReference for that representation.
*
* @return InstanceReference|array|null
*/
public function normalizeInstanceReference(InstanceReference|string|InstanceKey|array|null $instanceReferenceOrGuidOrInstanceKey) : InstanceReference|array|null
{
if ($instanceReferenceOrGuidOrInstanceKey === null)
return null;
if (is_array($instanceReferenceOrGuidOrInstanceKey))
{
$arry = array();
foreach ($instanceReferenceOrGuidOrInstanceKey as $instanceRef)
{
$arry[] = $this->normalizeInstanceReference($instanceRef);
}
return $arry;
}
else if (is_string($instanceReferenceOrGuidOrInstanceKey) || $instanceReferenceOrGuidOrInstanceKey instanceof UUID)
{
// assume GUID
return $this->getInstanceByGlobalIdentifier($instanceReferenceOrGuidOrInstanceKey);
}
else if ($instanceReferenceOrGuidOrInstanceKey instanceof InstanceKey)
{
return $this->getInstanceByKey($instanceReferenceOrGuidOrInstanceKey);
}
else if ($instanceReferenceOrGuidOrInstanceKey instanceof InstanceReference)
{
return $instanceReferenceOrGuidOrInstanceKey;
}
echo ("ERR");
return null;
}
public function getTranslationValue($sourceInstance, $relationshipInstance, $defaultValue = null)
{
$sourceInstance = $this->normalizeInstanceReference($sourceInstance);
$relationshipInstance = $this->normalizeInstanceReference($relationshipInstance);
$ctx = new OmsContext();
$m_Translatable__get__Translation_Value_for_Relationship_parm = $this->getInstanceByGlobalIdentifier(KnownMethodGuids::Translatable__get__Translation_Value_for_Relationship_parm);
$ctx->setWorkData(KnownClassGuids::Relationship, $relationshipInstance);
$mb_Translatable__get__Translation_Value_for_Relationship_parm = $this->executeMethodReturningAttribute($m_Translatable__get__Translation_Value_for_Relationship_parm, $ctx);
// Translatable@get Translation Value for Relationship parm(GRA)*S(public)[ramb]
// loop on instance seTranslation Value for Relationship parm(GRA)*S(public)[ramb]
// loop on instance settTranslation Value for Relationship parm(GRA)*S(public)[ramb]
// loop on instance set: Translatable@get Translations for Effective User Language(GRS)*S[rsmb]
// ---- Translatable@get Translations for Language parm(GRS)*S[rsmb]
// ---- Language => User@get Effective Language(SSC)[rsmb]
// ---- ---- if User@get Current Language then User@get Current Language
// ---- ---- if not User@get Current Language then Tenant@get Default Language
// get attribute: Translation@get Value(GA)[ramb]
}
public function getRelatedTasks(InstanceReference $inst)
{
$instParent = $this->getParentClass($inst);
$relatedTasks = [];
$instInstance = $this->getInstanceByGlobalIdentifier(KnownClassGuids::Instance);
$relatedTasks0 = $this->getRelatedInstances($instInstance, KnownRelationshipGuids::Class__has_related__Task);
foreach ($relatedTasks0 as $task)
{
$relatedTasks[] = $task;
}
$relatedTasks1 = $this->getRelatedInstances($instParent, KnownRelationshipGuids::Class__has_related__Task);
foreach ($relatedTasks1 as $task)
{
$relatedTasks[] = $task;
}
$superclasses = $this->getRelatedInstances($instParent, KnownRelationshipGuids::Class__has_super__Class);
foreach ($superclasses as $superclass)
{
$relatedTasks2 = $this->getRelatedInstances($superclass, KnownRelationshipGuids::Class__has_related__Task);
foreach ($relatedTasks2 as $task)
{
$relatedTasks[] = $task;
}
}
return $relatedTasks;
}
public function getNthRelatedInstance(InstanceReference $inst, InstanceReference|string|InstanceKey|array $rel, int $index)
{
$rel = $this->normalizeInstanceReference($rel);
$relInsts = $this->getRelatedInstances($inst, $rel);
return $relInsts[$index];
}
/**
* Checks to ensure the given value is of the appropriate type for the specified work data.
*
* @return bool true if the given value is of the appropriate type; false otherwise.
*/
public function validateWorkDataType(InstanceReference $instWorkData, mixed $value, &$expectedTypeName, &$actualTypeName)
{
$actualTypeName = gettype($value);
if (is_string($value))
{
$expectedTypeName = "Text Attribute";
if ($this->is_a($instWorkData, KnownClassGuids::TextAttribute))
{
return true;
}
}
else if (is_int($value) || is_float($value))
{
$expectedTypeName = "Numeric Attribute";
// int and float should only be assigned to Numeric Attribute
if ($this->is_a($instWorkData, KnownClassGuids::NumericAttribute))
{
return true;
}
}
else if ($value instanceof InstanceReference)
{
// instance references can be assigned to Work Sets and all sorts of other stuff
if ($this->is_a($instWorkData, KnownClassGuids::WorkSet))
{
$expectedTypeName = "Work Set";
// but if our Work Set declares a `Work Set.has valid Class` then we should validate that
$workDataHasValidClasses = $this->getRelatedInstances($instWorkData, KnownRelationshipGuids::Work_Set__has_valid__Class);
if ($workDataHasValidClasses !== null && count($workDataHasValidClasses) > 0)
{
// loop through all valid classes and check them
foreach ($workDataHasValidClasses as $validClass)
{
if ($this->is_a($value, $validClass))
{
$expectedTypeName = $this->getAttributeValue($validClass, KnownAttributeGuids::Name);
// our work set declares a valid class, and it passes
return true;
}
}
// none of the valid classes pass validation for $instWorkData
$actualTypeName = $this->getAttributeValue($this->getParentClass($value), KnownAttributeGuids::Name);
$expectedTypeName = $this->getAttributeValue($validClass, KnownAttributeGuids::Name);
return false;
}
// this work set doesn't care whether or not $instWorkData passes validation
return true;
}
else if ($this->is_a($instWorkData, KnownClassGuids::Clasz))
{
// Work Data is a Class, so make sure the value is of that class
if (!$this->is_a($value, $instWorkData))
{
$actualTypeName = $this->getAttributeValue($this->getParentClass($value), KnownAttributeGuids::Name);
$expectedTypeName = $this->getAttributeValue($instWorkData, KnownAttributeGuids::Name);
return false;
}
return true;
}
// we are not a work set, so we can't validate anything
return true;
}
// none of our validations pass
return false;
}
public function buildAccessKeyForOmsAttachment($fileInstance, $entropy)
{
/*
if (!entropy.ContainsKey(this.GetInstanceKey(inst)))
{
byte[] entropyData = new byte[256];
random.NextBytes(entropyData);
entropy[this.GetInstanceKey(inst)] = entropyData;
}
string entropy_co = Convert.ToBase64String(entropy[this.GetInstanceKey(inst)]);
string guid = inst.GlobalIdentifier.ToString();
long timestamp = DateTime.Now.Ticks;
string originalFileName = this.GetAttributeValue<string>(inst, KnownAttributeGuids.Text.Name);
string ft_co = String.Format("{0}?oms-attachments/{1}?{2}??{3}", entropy_co, guid, timestamp, originalFileName);
string base64 = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(ft_co));
string safeBase64 = MBS.Framework.Conversion.Base64ToUrlSafeBase64(base64);
return safeBase64;
*/
$entropy_co = base64_encode("lalalala");
//$timestamp = (new \DateTime())->
$timestamp = "112340340";
$originalFileName = "lalala.png";
$ft_co = $entropy_co . "?oms-attachments/" . $fileInstance->GlobalIdentifier . "?" . $timestamp . "??" . $originalFileName;
return base64_encode($ft_co);
}
public function getStackTrace(array $arr)
{
$sr = "";
$ct = count($arr);
for ($i = 0; $i < $ct; $i++)
{
if ($arr[$i] !== null)
{
$sr .= $arr[$i]->InstanceKey->__toString();
}
if ($i < $ct - 1)
{
$sr .= ":";
}
}
return $sr;
}
private function createHtmlLinkToInstanceReference($val)
{
if ($val === null)
{
return "";
}
return "<a href=\"" . System::ExpandRelativePath("~/d/inst/" . $val->InstanceKey . ".htmld") . "\">" . $val->InstanceKey . "</a>";
}
public function getStackTraceWithLinks(array $arr)
{
$sr = "";
$ct = count($arr);
for ($i = 0; $i < $ct; $i++)
{
if ($arr[$i] !== null)
{
$sr .= $this->createHtmlLinkToInstanceReference($arr[$i]);
}
if ($i < $ct - 1)
{
$sr .= ":";
}
}
return $sr;
}
public function getAttachmentUrl(InstanceReference $fileInstance)
{
$entropy = null;
$accessKey = $this->buildAccessKeyForOmsAttachment($fileInstance, $entropy);
return "/" . $this->getTenantName() . "/attachment/" . $fileInstance->InstanceKey . "/" . $accessKey;
}
public function executeReturningAttribute(OmsContext $context, InstanceReference $inst)
{
$value = $this->execute($context, $inst);
if ($value !== null)
{
$val = $context->getWorkData($value);
return $val;
}
return null;
}
public function executeAndEvaluateWorkData(OmsContext $context, InstanceReference $inst)
{
$result = $this->execute($context, $inst);
if ($this->is_a($result, KnownClassGuids::WorkSet))
{
return $context->getWorkData($result);
}
return $result;
}
public function execute(OmsContext $context, InstanceReference $inst, $classesLookupWorkData = true, ?array $parms = null)
{
$instParent = $this->getParentClass($inst);
$methodImplementation = $this->getMethodImplementation($instParent);
if ($methodImplementation !== null)
{
$retval = $methodImplementation->execute($this, $context, $inst, $parms); // $this->executeMethod($context, $inst, $parms);
}
else if ($instParent->GlobalIdentifier->__is_equal(UUID::parse(KnownClassGuids::ReturnAttributeMethodBinding))
|| ($instParent->GlobalIdentifier->__is_equal(UUID::parse(KnownClassGuids::ReturnInstanceSetMethodBinding)))
|| ($instParent->GlobalIdentifier->__is_equal(UUID::parse(KnownClassGuids::ProcessUpdatesMethodBinding))))
{
$methodBindingExecutesMethod = $this->getRelatedInstance($inst, KnownRelationshipGuids::Method_Binding__executes__Method);
if ($methodBindingExecutesMethod === null)
{
echo ("Method Binding.executes Method[" . KnownRelationshipGuids::Method_Binding__executes__Method . "] not found for " . $inst->InstanceKey);die();
}
$parameterAssignments = $this->getRelatedInstances($inst, KnownRelationshipGuids::Method_Binding__has__Parameter_Assignment);
foreach ($parameterAssignments as $parameterAssignment)
{
$this->applyParameterAssignment($context, $parameterAssignment);
}
/*
if (is_array(value: $parms))
{
foreach ($parms as $gid => $value)
{
$context->setWorkData($gid, $value);
}
}
*/
// echo ("MB stack: " . $methodInstance->InstanceKey . ":" . $methodBindingExecutesMethod->InstanceKey);
$retval = $this->execute($context, $methodBindingExecutesMethod, $parms);
}
else if (
// $this->is_a($inst, UUID::parse(KnownClassGuids::TextAttribute))
//|| $this->is_a($inst, UUID::parse(KnownClassGuids::NumericAttribute))
//|| $this->is_a($inst, UUID::parse(KnownClassGuids::DateAttribute))
// || $this->is_a($inst, UUID::parse(KnownClassGuids::BooleanAttribute))
$this->is_a($inst, UUID::parse(KnownClassGuids::WorkSet))
|| ($this->is_a($inst, UUID::parse(KnownClassGuids::Clasz)) && $classesLookupWorkData)
)
{
//return $context->getWorkData($inst);
$retval = $context->getWorkData($inst);
}
else
{
trigger_error("execute: unsupported class '" . $instParent->GlobalIdentifier . "' [" . $instParent->InstanceKey . "]");
$retval = $inst;
}
return $retval;
}
public function applyParameterAssignment(OmsContext $context, InstanceReference $parameterAssignment)
{
$evaluateWorkData = $this->getAttributeValue($parameterAssignment, KnownAttributeGuids::EvaluateWorkSet, false);
$assignsFromWorkData = $this->getRelatedInstance($parameterAssignment, KnownRelationshipGuids::Parameter_Assignment__assigns_from__Executable_returning_Work_Data);
$assignsToParm = $this->getRelatedInstance($parameterAssignment, KnownRelationshipGuids::Parameter_Assignment__assigns_to__Work_Data);
if ($assignsFromWorkData !== null && $assignsToParm !== null)
{
$workData = $this->execute($context, $assignsFromWorkData);
if ($workData !== null)
{
$workDataValue = $context->getWorkData($workData);
// $context->getWorkData($assignsFromWorkData); //
if (
is_string($workDataValue) ||
$this->is_a($workData, KnownClassGuids::WorkSet)
)
{
// !! HACK !!
$workData = $workDataValue;
}
//echo ("update with " . $assignsToParm->InstanceKey . " = " . $workDataValue);
$context->setWorkData($assignsToParm, $workData);
}
else
{
// echo ("setting null on " . $assignsToParm->InstanceKey);
$context->setWorkData($assignsToParm, $assignsFromWorkData);
}
}
}
public function evaluateConditions(OmsContext $context, ?array $trueConditions, ?array $falseConditions)
{
if ($trueConditions !== null)
{
foreach ($trueConditions as $condition)
{
$val = $this->executeReturningAttribute($context, $condition);
if (!$val)
{
return false;
}
}
}
if ($falseConditions !== null)
{
foreach ($falseConditions as $condition)
{
$val = $this->executeReturningAttribute($context, $condition);
if ($val)
{
return false;
}
}
}
return true;
}
public function printWorkData(array $workData)
{
foreach ($workData as $key => $value)
{
echo ($key . " == ");
if ($value instanceof InstanceReference)
{
echo ("[" . $this->createHtmlLinkToInstanceReference($value) . "]");
}
else if (is_array($value))
{
echo("[ ");
foreach ($value as $val)
{
if ($val instanceof InstanceReference)
{
echo ("[" . $this->createHtmlLinkToInstanceReference($value) . "]");
}
else
{
echo ("'" . $val . "'");
}
echo (", ");
}
echo (" ]");
}
else
{
echo ("'" . $value . "'");
}
echo (" ; ");
}
}
public function CompareInstanceSets_ExactMatch(InstanceReference|array|null $left, InstanceReference|array|null $right)
{
//echo ("CIS: " . $left->InstanceKey . " ?? " . $right->InstanceKey);
if ($left === null && $right === null)
return true;
if ($left === null || $right === null)
return false;
if (is_array($left) && is_array($right))
{
// Both are Instance Sets, so we can make some optimizations
if (count($left) !== count($right))
return false;
$is = array_intersect($left, $right);
return count($is) === count($left);
}
else
{
// Instance Set and Instance cannot be compared, for now
if (is_array($left) || is_array($right))
{
return false;
}
}
// If we get here, $left and $right should both be single instances
if ($left->GlobalIdentifier->__is_equal($right->GlobalIdentifier))
{
return true;
}
return false;
}
private function __is_a_impl(InstanceReference $inst, InstanceReference $what, int $reentrant_counter)
{
if ($reentrant_counter > 10)
{
if ($reentrant_counter == 11)
{
echo("recursion detected!\n");
}
echo("__is_a_impl!(" . $inst->InstanceKey . ", " . $what->InstanceKey . ")\n");
if ($reentrant_counter > 30)
{
die();
}
}
$pclass = $this->getParentClass($inst);
if ($pclass === null)
return false;
if ($pclass->__is_equal($what))
{
return true;
}
if (!($pclass->InstanceKey->ClassIndex == 1 && $pclass->InstanceKey->InstanceIndex == 1))
{
$pclassSuperclasses = $this->getRelatedInstances($pclass, KnownRelationshipGuids::Class__has_super__Class);
foreach ($pclassSuperclasses as $pclassSuperclass)
{
if ($what->GlobalIdentifier->__is_equal($pclassSuperclass->GlobalIdentifier))
{
return true;
}
}
}
return false;
}
public function is_a(InstanceReference|string|InstanceKey|array|null $inst, InstanceReference|string|InstanceKey $what)
{
if ($inst === null)
{
return false;
}
if (is_array($inst))
{
return false;
}
$inst = $this->normalizeInstanceReference($inst);
$what = $this->normalizeInstanceReference($what);
return $this->__is_a_impl($inst, $what, 0);
}
public function setSessionAttributeValue(OmsContext $context, InstanceReference $instance, mixed $value)
{
$context->setTemporaryVariable($instance, $value);
}
public function getSessionAttributeValue(OmsContext $context, InstanceReference $instance, mixed $defaultValue = null)
{
return $context->getTemporaryVariable($instance, $defaultValue);
}
private ?InstanceReference $_currentUser = null;
public function setCurrentUser(?InstanceReference $userInstance)
{
$this->_currentUser = $userInstance;
}
public function getCurrentUser() : ?InstanceReference
{
return $this->_currentUser;
}
public abstract function createInstanceOf(InstanceReference $classInstance) : ?InstanceReference;
public function createContext()
{
return new OmsContext();
}
public function isConnected()
{
return true;
}
}
?>

View File

@ -2,6 +2,8 @@
namespace Mocha\Oms;
use Mocha\Core\Oms;
abstract class DatabaseOms extends Oms
{

View File

@ -0,0 +1,342 @@
<?php
namespace Mocha\Oms;
use Mocha\Core\InstanceKey;
use Mocha\Core\InstanceReference;
use Mocha\Core\Oms;
use Mocha\Core\TenantReference;
use Phast\UUID;
class HttpRequestMethod
{
const GET = 1;
const POST = 2;
}
class HttpPostDataFormat
{
const URLENCODED = 1;
const JSON = 2;
}
function http_build_query2(array $ary)
{
$retval = "";
foreach ($ary as $key => $value)
{
$retval .= urlencode($key) . "=" . urlencode($value) . "&";
}
return substr($retval, 0, strlen($retval) - 1);
}
class HttpOmsClient extends Oms
{
public string $ServerName;
public int $PortNumber;
public function __construct(string $serverName, int $portNumber)
{
parent::__construct();
$this->ServerName = $serverName;
$this->PortNumber = $portNumber;
}
private function curl_new(string $relativeUrl) : \CurlHandle | null
{
$curl = \curl_init("http://" . $this->ServerName . ":" . $this->PortNumber . $relativeUrl);
if ($curl instanceof \CurlHandle)
{
return $curl;
}
return null;
}
private function curl_request($relativeUrl, $method = HttpRequestMethod::GET, string | array | null $data = null, $dataFormat = HttpPostDataFormat::URLENCODED) : string | null
{
//trigger_error("curl_request for url " . $relativeUrl);
$curl = $this->curl_new($relativeUrl);
if ($method == HttpRequestMethod::POST)
{
trigger_error("POST " . $relativeUrl);
\curl_setopt($curl, CURLOPT_POST, true);
if ($data !== null)
{
if (is_string($data))
{
\curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
else if (is_array($data))
{
if ($dataFormat == HttpPostDataFormat::URLENCODED)
{
trigger_error("POST(" . count($data) . ") " . http_build_query2($data));
\curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query2($data));
}
else
{
\curl_setopt($curl, CURLOPT_POSTFIELDS, \json_encode($data));
}
}
}
}
\curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = \curl_exec($curl);
\curl_close($curl);
return $response;
}
private function curl_request_json($relativeUrl, $method = HttpRequestMethod::GET, string | array | null $data = null, $dataFormat = HttpPostDataFormat::URLENCODED) : array | null
{
$result = $this->curl_request($relativeUrl, $method, $data, $dataFormat);
if ($result == null)
{
return null;
}
$json = json_decode($result, true);
return $json;
}
protected function assignRelationshipInternal(InstanceReference $sourceInstance, InstanceReference $relationshipInstance, array|InstanceReference $targetInstances, \DateTime|null $effectiveDate = null)
{
if (!is_array($targetInstances))
{
$targetInstances = [ $targetInstances ];
}
// ? valid actions for 'relationship' are: add, remove, update
// ? ---- add: adds the specified instances to the existing relationship
// ? ---- remove: removes the specified instances from the existing relationship
// ? ---- update: clears the existing relationship and replaces it completely with the specified instances
$count = count($targetInstances);
$data = array
(
"count" => $count
);
for ($i = 0; $i < $count; $i++)
{
$data["item" . $i] = $targetInstances[$i]->GlobalIdentifier->__toString();
}
$json = $this->curl_request_json("/tenants/" . $this->getTenantName() . "/instances/" . $sourceInstance->GlobalIdentifier . "/relationships/" . $relationshipInstance->GlobalIdentifier . "/update", HttpRequestMethod::POST, $data);
if ($json["result"] == "success")
{
return true;
}
return false;
}
protected function getAttributeValueInternal(InstanceReference $sourceInstance, InstanceReference $attributeInstance, $defaultValue = null, $effectiveDate = null): string|null
{
$result = $this->curl_request("/tenants/" . $this->getTenantName() . "/instances/" . $sourceInstance->GlobalIdentifier . "/attributes/" . $attributeInstance->GlobalIdentifier . "/current");
return $result;
// print_r($json);
}
protected function getRelatedInstancesInternal(InstanceReference $sourceInstance, InstanceReference $relationshipInstance, \DateTime|null $effectiveDate = null): array|null
{
$json = $this->curl_request_json("/tenants/" . $this->getTenantName() . "/instances/" . $sourceInstance->GlobalIdentifier . "/relationships/" . $relationshipInstance->GlobalIdentifier);
if ($json["result"] == "success")
{
$ary = $json["value"];
$retval = array();
foreach ($ary as $inst)
{
$retval[] = new InstanceReference(null, InstanceKey::parse($inst["iid"]), UUID::parse($inst["globalIdentifier"]));
}
return $retval;
}
return [ ];
}
public function isConnected() : bool
{
$json = $this->curl_request_json("/ping");
if ($json["result"] == "success")
{
return true;
}
return false;
}
protected function removeRelationshipInstanceInternal(string|InstanceKey|InstanceReference $sourceInstance, string|InstanceKey|InstanceReference $relationshipInstance, array|string|InstanceKey|InstanceReference $targetInstances, \DateTime|null $effectiveDate = null)
{
}
protected function setAttributeValueInternal(InstanceReference $sourceInstance, InstanceReference $attributeInstance, mixed $value, \DateTime|null $effectiveDate = null)
{
$json = $this->curl_request_json("/tenants/" . $this->getTenantName() . "/instances/" . $sourceInstance->GlobalIdentifier . "/attributes/" . $attributeInstance->GlobalIdentifier . "/update", HttpRequestMethod::POST, array
(
"value" => $value
));
if ($json["result"] == "success")
{
return true;
}
return false;
}
public function getInstancesByAttributes($parms)
{
// FIXME: NOT IMPLEMENTED
//usage:
// getInstanceByAttributes (array ( getInstanceByGlobalIdentifier(NAME_ATTRIBUTE) => "zq-developer" ))
$insts = $this->getInstances();
$insts2 = [ ];
foreach ($insts as $inst)
{
foreach ($parms as $key => $value)
{
$parmInst = $this->normalizeInstanceReference($key);
if ($this->getAttributeValue($inst, $parmInst) == $value)
{
$insts2[] = $inst;
}
}
}
return $insts2;
}
public function getInstancesOfByAttributes(array|InstanceKey|InstanceReference|string|null $parentClass, array $parms)
{
$parentClass = $this->normalizeInstanceReference($parentClass);
// FIXME: NOT IMPLEMENTED
//usage:
// getInstanceByAttributes (array ( getInstanceByGlobalIdentifier(NAME_ATTRIBUTE) => "zq-developer" ))
if ($parentClass !== null)
{
$insts = $this->getInstancesOf($parentClass);
}
else
{
$insts = $this->getInstances();
}
$insts2 = [ ];
foreach ($insts as $inst)
{
foreach ($parms as $key => $value)
{
// echo ($key . " = " . $value . " ? ");
$parmInst = $this->normalizeInstanceReference($key);
$actualValue = $this->getAttributeValue($inst, $parmInst);
if ($actualValue == $value)
{
$insts2[] = $inst;
}
}
}
return $insts2;
}
public function getInstanceData(array|InstanceKey|InstanceReference|string|null $inst)
{
$inst = $this->normalizeInstanceReference($inst);
$json = $this->curl_request_json("/tenants/" . $this->getTenantName() . "/instances/" . $inst->GlobalIdentifier);
if (array_key_exists("result", $json))
{
// V2 should have result
if ($json["result"] == "success")
{
return $json["value"];
}
}
else
{
// HACK
return $json;
}
return null;
}
protected function getInstancesInternal() : array
{
$json = $this->curl_request_json("/tenants/" . $this->getTenantName() . "/instances");
if ($json["result"] == "success")
{
$ary = $json["instances"];
$retval = array();
foreach ($ary as $inst)
{
$retval[] = new InstanceReference(null, InstanceKey::parse($inst["iid"]), UUID::parse($inst["globalIdentifier"]));
}
return $retval;
}
return [ ];
}
public function getInstanceFromDatabase($value)
{
if ($value["class_id"] === null)
return null;
$retval = new InstanceReference($value["id"], new InstanceKey($value["class_id"], $value["inst_id"]), $value["global_identifier"]);
return $retval;
}
/**
* Gets the tenant with the specified name, or NULl if no tenant with the specified name exists on the server.
*
* @param string $tenantName the name of the desired tenant
*
* @return ?TenantReference
*/
public function getTenantByName(string $tenantName) : ?TenantReference
{
$json = $this->curl_request_json("/tenants");
$i = 0;
if ($json["result"] == "success")
{
foreach ($json["tenants"] as $tenant)
{
if ($tenant == $tenantName)
{
return new TenantReference($i, $tenant, null);
}
$i++;
}
}
return null;
}
public function getResponse($element)
{
$json = $this->curl_request_json("/tenants/" . $this->getTenantName() . "/instances/" . $element->InstanceKey . "/element");
return $json;
}
/**
* Gets the instance with the specified instance key.
*/
public function getInstanceByKey(InstanceKey|string $key) : ?InstanceReference
{
$result = $this->curl_request_json("/tenants/" . $this->getTenantName() . "/instances/" . $key);
return new InstanceReference(null, InstanceKey::parse($result["instanceKey"]), UUID::parse($result["globalIdentifier"]));
}
/**
* Gets the instance with the specified global identifier.
*/
public function getInstanceByGlobalIdentifier(UUID|string $inst) : ?InstanceReference
{
$result = $this->curl_request_json("/tenants/" . $this->getTenantName() . "/instances/" . $inst);
return new InstanceReference(null, InstanceKey::parse($result["instanceKey"]), UUID::parse($result["globalIdentifier"]));
}
public function createInstanceOf(InstanceReference $classInstance) : ?InstanceReference
{
$result = $this->curl_request_json("/tenants/" . $this->getTenantName() . "/instances/create", HttpRequestMethod::POST, array(
"parentClassIid" => $classInstance->GlobalIdentifier
), HttpPostDataFormat::URLENCODED);
if ($result["result"] == "success")
{
return new InstanceReference(null, InstanceKey::parse($result["value"]["iid"]), UUID::parse($result["value"]["globalIdentifier"]));
}
return null;
}
}
?>

View File

@ -12,16 +12,6 @@
{
private \PDO $PDO;
private ?InstanceReference $_currentUser = null;
public function setCurrentUser(?InstanceReference $userInstance)
{
$this->_currentUser = $userInstance;
}
public function getCurrentUser() : ?InstanceReference
{
return $this->_currentUser;
}
public function query($query, array $parms)
{
$stmt = $this->PDO->prepare($query);

View File

@ -1,928 +0,0 @@
<?php
namespace Mocha\Oms;
use Mocha\Core\InstanceKey;
use Mocha\Core\InstanceReference;
use Mocha\Core\KnownClassGuids;
use Mocha\Core\KnownInstanceGuids;
use Mocha\Core\KnownAttributeGuids;
use Mocha\Core\KnownMethodBindingGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Core\TenantReference;
use Mocha\Oop\MethodImplementation;
use Mocha\Oop\Methods\BuildAttributeMethod;
use Phast\System;
use Phast\Utilities\Stopwatch;
use Phast\UUID;
abstract class Oms
{
public ?array $MethodImplementations;
public function __construct()
{
$this->_tenant = null;
$this->_pclass_cache = null;
$this->MetadataExceptions = array();
$this->MethodImplementations = null;
}
public abstract function getUserByUserName(string $username) : ?InstanceReference;
private function registerMethodImplementation(InstanceReference|string|InstanceKey $methodImplementationClass, MethodImplementation $implementation)
{
$methodImplementationClass = $this->normalizeInstanceReference($methodImplementationClass);
$this->MethodImplementations[$methodImplementationClass->GlobalIdentifier->__toString()] = $implementation;
}
private function initializeMethodImplementations()
{
$this->registerMethodImplementation(KnownClassGuids::BuildAttributeMethod, new \Mocha\Oop\MethodImplementations\BuildAttributeMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::ConditionalSelectAttributeMethod, new \Mocha\Oop\MethodImplementations\ConditionalSelectAttributeMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::ConditionalSelectFromInstanceSetMethod, new \Mocha\Oop\MethodImplementations\ConditionalSelectInstanceSetMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::EvaluateBooleanExpressionMethod, new \Mocha\Oop\MethodImplementations\EvaluateBooleanExpressionMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::GetAttributeBySystemRoutineMethod, new \Mocha\Oop\MethodImplementations\GetAttributeBySystemRoutineMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::GetAttributeMethod, new \Mocha\Oop\MethodImplementations\GetAttributeMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::GetInstanceSetBySystemRoutineMethod, new \Mocha\Oop\MethodImplementations\GetInstanceSetBySystemRoutineMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::GetInstancesMethod, new \Mocha\Oop\MethodImplementations\GetInstancesMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::GetReferencedAttributeMethod, new \Mocha\Oop\MethodImplementations\GetReferencedAttributeMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::GetReferencedInstanceSetMethod, new \Mocha\Oop\MethodImplementations\GetReferencedInstanceSetMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::GetSpecifiedInstancesMethod, new \Mocha\Oop\MethodImplementations\GetSpecifiedInstancesMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::ProcessRelatedUpdatesMethod, new \Mocha\Oop\MethodImplementations\ProcessRelatedUpdatesMethodImplementation());
$this->registerMethodImplementation(KnownClassGuids::SelectFromInstanceSetMethod, new \Mocha\Oop\MethodImplementations\SelectFromInstanceSetMethodImplementation());
}
private function getMethodImplementation(InstanceReference|string|InstanceKey $methodImplementationClass)
{
if ($this->MethodImplementations === null)
{
// initialize method implementations
// we cannot do this in the constructor, since it relies on getInstanceByGlobalIdentifier
// which fails if the current tenant is null, and we need OMS to get the current tenant...
$this->initializeMethodImplementations();
}
$methodImplementationClass = $this->normalizeInstanceReference($methodImplementationClass);
$key = $methodImplementationClass->GlobalIdentifier->__toString();
if (array_key_exists($key, $this->MethodImplementations))
{
return $this->MethodImplementations[$key];
}
return null;
}
/**
* @var array
*/
public $MetadataExceptions;
/**
* Gets ALL instances on this OMS.
*/
public function getInstances() : array
{
return [ ];
}
/**
* Gets the instance with the specified global identifier.
*/
public function getInstanceByGlobalIdentifier(UUID|string $inst) : ?InstanceReference
{
return null;
}
/**
* Indices are 1-based
*/
public function getNthInstanceOf(InstanceReference|string|InstanceKey $sourceInstance, int $index, $defaultValue = null)
{
$insts = $this->getRelatedInstances($sourceInstance, KnownRelationshipGuids::Class__has__Instance);
if (count($insts) > 0)
{
return $insts[$index - 1];
}
return $defaultValue;
}
public function instanceKeysToInstances(array|string|null $instanceKeys)
{
$insts = [ ];
if ($instanceKeys === null)
{
return $insts;
}
if (is_string($instanceKeys))
{
$instanceKeys = explode(",", $instanceKeys);
}
foreach ($instanceKeys as $instanceKey)
{
if (is_string($instanceKey))
{
$instanceKey = InstanceKey::parse($instanceKey);
}
if ($instanceKey !== null)
{
$insts[] = $this->getInstanceByKey($instanceKey);
}
}
return $insts;
}
public function getRelatedInstances(InstanceReference|string|InstanceKey $sourceInstance, InstanceReference|string|InstanceKey|null $relationshipInstance, \DateTime $effectiveDate = null) : ?array
{
$tenant = $this->getTenant();
if ($tenant === null)
{
trigger_error("tenant cannot be null", \E_USER_ERROR);
return null;
}
$sourceInstance = $this->normalizeInstanceReference($sourceInstance);
$relationshipInstance = $this->normalizeInstanceReference($relationshipInstance);
if ($relationshipInstance === null)
{
//echo ("Relationship Instance is null");
return null;
}
// trigger_error("MADI debug: entering " . get_class($this) . "::getRelatedInstancesInternal");
// $stopwatch = new Stopwatch();
// $stopwatch->start();
$insts = $this->getRelatedInstancesInternal($sourceInstance, $relationshipInstance, $effectiveDate);
// $stopwatch->stop();
// trigger_error("MADI debug: exiting " . get_class($this) . "::getRelatedInstancesInternal (took " . $stopwatch->getElapsedTime() . "s)");
return $insts;
}
protected abstract function getRelatedInstancesInternal(InstanceReference $sourceInstance, InstanceReference $relationshipInstance, \DateTime $effectiveDate = null) : ?array;
public function getRelatedInstance(InstanceReference|string|InstanceKey $sourceInstance, InstanceReference|string|InstanceKey $relationshipInstance, \DateTime $effectiveDate = null) : ?InstanceReference
{
$insts = $this->getRelatedInstances($sourceInstance, $relationshipInstance, $effectiveDate);
if ($insts === null)
return null;
if (count($insts) === 0)
return null;
return $insts[0];
}
/**
* Gets the parent class Instance of the specified Instance.
*/
public function getParentClass(InstanceReference $inst) : ?InstanceReference
{
$gid = $inst->GlobalIdentifier->__toString();
$forClass = $this->getRelatedInstance($inst, $this->getInstanceByGlobalIdentifier(KnownRelationshipGuids::Instance__for__Class));
return $forClass;
}
/**
* Gets the instance representing the default tenant.
*/
public function getTenantInstance() : ?InstanceReference
{
return $this->getInstanceByGlobalIdentifier(KnownInstanceGuids::DefaultTenant);
}
/**
* Gets the value of the given attribute on the specified instance.
*/
public function getAttributeValue(InstanceReference|string|InstanceKey|null $sourceInstance, InstanceReference|string|InstanceKey|null $attributeInstance, $defaultValue = null, $effectiveDate = null) : ?string
{
$tenant = $this->getTenant();
if ($tenant === null)
{
trigger_error("tenant cannot be null", \E_USER_ERROR);
return null;
}
$sourceInstance = $this->normalizeInstanceReference($sourceInstance);
$attributeInstance = $this->normalizeInstanceReference($attributeInstance);
if ($sourceInstance === null || $attributeInstance === null)
return $defaultValue;
return $this->getAttributeValueInternal($sourceInstance, $attributeInstance, $defaultValue, $effectiveDate);
}
protected abstract function getAttributeValueInternal(InstanceReference $sourceInstance, InstanceReference $attributeInstance, $defaultValue = null, $effectiveDate = null) : ?string;
public function setAttributeValue(InstanceReference|string|InstanceKey $sourceInstance, InstanceReference|string|InstanceKey $attributeInstance, mixed $value, ?\DateTime $effectiveDate = null)
{
$tenant = $this->getTenant();
if ($tenant === null)
{
trigger_error("tenant cannot be null", \E_USER_ERROR);
return null;
}
$sourceInstance = $this->normalizeInstanceReference($sourceInstance);
$attributeInstance = $this->normalizeInstanceReference($attributeInstance);
$this->setAttributeValueInternal($sourceInstance, $attributeInstance, $value, $effectiveDate);
}
protected abstract function setAttributeValueInternal(InstanceReference $sourceInstance, InstanceReference $attributeInstance, mixed $value, ?\DateTime $effectiveDate = null);
public function getDefaultTaskUrl(InstanceReference $inst) : ?string
{
$instParent = $this->getParentClass($inst);
if ($instParent === null)
return null;
$instDefaultTask = $this->getRelatedInstance($instParent, KnownRelationshipGuids::Class__has_default__Task);
if ($instDefaultTask != null)
{
// !FIXME: check to see if the task is authorized for the current user
// (e.g. this can be by if `User .has Security Domain` any in `Securable.has Security Domain`)
// e.g. if User has `Administrator` and Task has `Administrator`, return true
if (true) // ($oms->isTaskAuthorizedForUser($instDefaultTask, $oms->getCurrentUser()))
{
return System::ExpandRelativePath("~/d/inst/" . $instParent->InstanceKey . "/" . $inst->InstanceKey . ".htmld");
}
}
return null;
}
private $_instanceTextCache;
public function getInstanceText($inst)
{
if ($inst === null)
return "ERR: inst null";
if ($this->_instanceTextCache === null)
{
$this->_instanceTextCache = array();
}
if (array_key_exists($inst->GlobalIdentifier->__toString(), $this->_instanceTextCache))
{
return $this->_instanceTextCache[$inst->GlobalIdentifier->__toString()];
}
$parentClass = $this->getParentClass($inst);
if ($parentClass === null)
{
$this->MetadataExceptions[] = new OmsMetadataException("Parent class empty", array
(
"For Instance" => $inst
));
return "ERR: no parent class for inst";
}
$instancesLabeledByRAMB = $this->getRelatedInstance($parentClass, KnownRelationshipGuids::Class__instances_labeled_by__Executable_returning_Attribute);
if ($instancesLabeledByRAMB !== null)
{
$context = new OmsContext();
$context->setWorkData($parentClass->GlobalIdentifier->__toString(), $inst);
$textAttr = $this->execute($context, $instancesLabeledByRAMB);
$text = $context->getWorkData($textAttr);
//$this->printWorkData($context->workData);
$this->_instanceTextCache[$inst->GlobalIdentifier->__toString()] = $text;
return $text;
}
else
{
//echo ("no RAMB");
}
return $this->getAttributeValue($inst, $this->getInstanceByGlobalIdentifier(KnownAttributeGuids::Name));
}
public function removeRelationshipInstances(InstanceReference|string|InstanceKey $sourceInstance, InstanceReference|string|InstanceKey $relationshipInstance)
{
$tenant = $this->getTenant();
if ($tenant === null)
{
trigger_error("tenant cannot be null", \E_USER_ERROR);
return null;
}
$sourceInstance = $this->normalizeInstanceReference($sourceInstance);
$relationshipInstance = $this->normalizeInstanceReference($relationshipInstance);
$targetInstances = $this->getRelatedInstances($sourceInstance, $relationshipInstance);
$this->removeRelationshipInstance($sourceInstance, $relationshipInstance, $targetInstances);
}
protected abstract function removeRelationshipInstanceInternal(InstanceReference|string|InstanceKey $sourceInstance, InstanceReference|string|InstanceKey $relationshipInstance, InstanceReference|string|InstanceKey|array $targetInstances, ?\DateTime $effectiveDate = null);
public function removeRelationshipInstance(InstanceReference|string|InstanceKey $sourceInstance, InstanceReference|string|InstanceKey $relationshipInstance, InstanceReference|string|InstanceKey|array $targetInstances, ?\DateTime $effectiveDate = null)
{
return $this->removeRelationshipInstanceInternal($sourceInstance, $relationshipInstance, $targetInstances, $effectiveDate);
}
public function assignRelationship(InstanceReference|string|InstanceKey $sourceInstance, InstanceReference|string|InstanceKey $relationshipInstance, InstanceReference|string|InstanceKey|array $targetInstances, ?\DateTime $effectiveDate = null)
{
$tenant = $this->getTenant();
if ($tenant === null)
{
trigger_error("tenant cannot be null", \E_USER_ERROR);
return null;
}
$sourceInstance = $this->normalizeInstanceReference($sourceInstance);
$relationshipInstance = $this->normalizeInstanceReference($relationshipInstance);
$targetInstances = $this->normalizeInstanceReference($targetInstances);
return $this->assignRelationshipInternal($sourceInstance, $relationshipInstance, $targetInstances, $effectiveDate);
}
protected abstract function assignRelationshipInternal(InstanceReference $sourceInstance, InstanceReference $relationshipInstance, InstanceReference|array $targetInstances, ?\DateTime $effectiveDate = null);
private $_tenant;
public function getTenant() : ?TenantReference
{
return $this->_tenant;
}
public function setTenant(TenantReference $tenant) : void
{
$oldTenant = $this->_tenant;
$this->_tenant = $tenant;
$this->onTenantChanged($oldTenant, $tenant);
}
public function onTenantChanged(TenantReference $oldTenant, TenantReference $newTenant)
{
}
public function getTenantName() : ?string
{
if ($this->_tenant !== null)
{
return $this->_tenant->Name;
}
return null;
}
/**
* Gets the tenant with the specified name, or NULl if no tenant with the specified name exists on the server.
*
* @param string $tenantName the name of the desired tenant
*
* @return ?TenantReference
*/
public function getTenantByName(string $tenantName) : ?TenantReference
{
return null;
}
public function getInstanceKeysString(array $instanceReferences, string $separator = ":")
{
$val = "";
$ct = count($instanceReferences);
for($i = 0; $i < $ct; $i++)
{
$val .= $instanceReferences[$i]->InstanceKey;
if ($i < $ct - 1)
{
$val .= $separator;
}
}
return $val;
}
public function printInstanceKeys(array $instanceReferences, string $separator = ":")
{
echo ($this->getInstanceKeysString($instanceReferences, $separator));
}
public function instanceSetContains(array /*<InstanceReference>*/ $haystack, InstanceReference|string|InstanceKey|UUID $needle)
{
$needle = $this->normalizeInstanceReference($needle);
foreach ($haystack as $v)
{
if ($v->DatabaseId == $needle->DatabaseId)
{
return true;
}
}
return false;
}
public function getInstancesOf(InstanceReference|string|InstanceKey|UUID $classInstance) : ?array
{
$classInstance = $this->normalizeInstanceReference($classInstance);
$instances = $this->getRelatedInstances($classInstance, KnownRelationshipGuids::Class__has__Instance);
return $instances;
}
/**
* Given an InstanceReference, GUID (string), or InstanceKey, return the normalized InstanceReference for that representation.
*
* @return InstanceReference|array|null
*/
public function normalizeInstanceReference(InstanceReference|string|InstanceKey|array|null $instanceReferenceOrGuidOrInstanceKey) : InstanceReference|array|null
{
if ($instanceReferenceOrGuidOrInstanceKey === null)
return null;
if (is_array($instanceReferenceOrGuidOrInstanceKey))
{
$arry = array();
foreach ($instanceReferenceOrGuidOrInstanceKey as $instanceRef)
{
$arry[] = $this->normalizeInstanceReference($instanceRef);
}
return $arry;
}
else if (is_string($instanceReferenceOrGuidOrInstanceKey) || $instanceReferenceOrGuidOrInstanceKey instanceof UUID)
{
// assume GUID
return $this->getInstanceByGlobalIdentifier($instanceReferenceOrGuidOrInstanceKey);
}
else if ($instanceReferenceOrGuidOrInstanceKey instanceof InstanceKey)
{
return $this->getInstanceByKey($instanceReferenceOrGuidOrInstanceKey);
}
else if ($instanceReferenceOrGuidOrInstanceKey instanceof InstanceReference)
{
return $instanceReferenceOrGuidOrInstanceKey;
}
echo ("ERR");
return null;
}
public function getTranslationValue($sourceInstance, $relationshipInstance, $defaultValue = null)
{
$sourceInstance = $this->normalizeInstanceReference($sourceInstance);
$relationshipInstance = $this->normalizeInstanceReference($relationshipInstance);
$ctx = new OmsContext();
$m_Translatable__get__Translation_Value_for_Relationship_parm = $this->getInstanceByGlobalIdentifier(KnownMethodGuids::Translatable__get__Translation_Value_for_Relationship_parm);
$ctx->setWorkData(KnownClassGuids::Relationship, $relationshipInstance);
$mb_Translatable__get__Translation_Value_for_Relationship_parm = $this->executeMethodReturningAttribute($m_Translatable__get__Translation_Value_for_Relationship_parm, $ctx);
// Translatable@get Translation Value for Relationship parm(GRA)*S(public)[ramb]
// loop on instance seTranslation Value for Relationship parm(GRA)*S(public)[ramb]
// loop on instance settTranslation Value for Relationship parm(GRA)*S(public)[ramb]
// loop on instance set: Translatable@get Translations for Effective User Language(GRS)*S[rsmb]
// ---- Translatable@get Translations for Language parm(GRS)*S[rsmb]
// ---- Language => User@get Effective Language(SSC)[rsmb]
// ---- ---- if User@get Current Language then User@get Current Language
// ---- ---- if not User@get Current Language then Tenant@get Default Language
// get attribute: Translation@get Value(GA)[ramb]
}
public function getRelatedTasks(InstanceReference $inst)
{
$instParent = $this->getParentClass($inst);
$relatedTasks = [];
$instInstance = $this->getInstanceByGlobalIdentifier(KnownClassGuids::Instance);
$relatedTasks0 = $this->getRelatedInstances($instInstance, KnownRelationshipGuids::Class__has_related__Task);
foreach ($relatedTasks0 as $task)
{
$relatedTasks[] = $task;
}
$relatedTasks1 = $this->getRelatedInstances($instParent, KnownRelationshipGuids::Class__has_related__Task);
foreach ($relatedTasks1 as $task)
{
$relatedTasks[] = $task;
}
$superclasses = $this->getRelatedInstances($instParent, KnownRelationshipGuids::Class__has_super__Class);
foreach ($superclasses as $superclass)
{
$relatedTasks2 = $this->getRelatedInstances($superclass, KnownRelationshipGuids::Class__has_related__Task);
foreach ($relatedTasks2 as $task)
{
$relatedTasks[] = $task;
}
}
return $relatedTasks;
}
public function getNthRelatedInstance(InstanceReference $inst, InstanceReference|string|InstanceKey|array $rel, int $index)
{
$rel = $this->normalizeInstanceReference($rel);
$relInsts = $this->getRelatedInstances($inst, $rel);
return $relInsts[$index];
}
/**
* Checks to ensure the given value is of the appropriate type for the specified work data.
*
* @return bool true if the given value is of the appropriate type; false otherwise.
*/
public function validateWorkDataType(InstanceReference $instWorkData, mixed $value, &$expectedTypeName, &$actualTypeName)
{
$actualTypeName = gettype($value);
if (is_string($value))
{
$expectedTypeName = "Text Attribute";
if ($this->is_a($instWorkData, KnownClassGuids::TextAttribute))
{
return true;
}
}
else if (is_int($value) || is_float($value))
{
$expectedTypeName = "Numeric Attribute";
// int and float should only be assigned to Numeric Attribute
if ($this->is_a($instWorkData, KnownClassGuids::NumericAttribute))
{
return true;
}
}
else if ($value instanceof InstanceReference)
{
// instance references can be assigned to Work Sets and all sorts of other stuff
if ($this->is_a($instWorkData, KnownClassGuids::WorkSet))
{
$expectedTypeName = "Work Set";
// but if our Work Set declares a `Work Set.has valid Class` then we should validate that
$workDataHasValidClasses = $this->getRelatedInstances($instWorkData, KnownRelationshipGuids::Work_Set__has_valid__Class);
if ($workDataHasValidClasses !== null && count($workDataHasValidClasses) > 0)
{
// loop through all valid classes and check them
foreach ($workDataHasValidClasses as $validClass)
{
if ($this->is_a($value, $validClass))
{
$expectedTypeName = $this->getAttributeValue($validClass, KnownAttributeGuids::Name);
// our work set declares a valid class, and it passes
return true;
}
}
// none of the valid classes pass validation for $instWorkData
$actualTypeName = $this->getAttributeValue($this->getParentClass($value), KnownAttributeGuids::Name);
$expectedTypeName = $this->getAttributeValue($validClass, KnownAttributeGuids::Name);
return false;
}
// this work set doesn't care whether or not $instWorkData passes validation
return true;
}
else if ($this->is_a($instWorkData, KnownClassGuids::Clasz))
{
// Work Data is a Class, so make sure the value is of that class
if (!$this->is_a($value, $instWorkData))
{
$actualTypeName = $this->getAttributeValue($this->getParentClass($value), KnownAttributeGuids::Name);
$expectedTypeName = $this->getAttributeValue($instWorkData, KnownAttributeGuids::Name);
return false;
}
return true;
}
// we are not a work set, so we can't validate anything
return true;
}
// none of our validations pass
return false;
}
public function buildAccessKeyForOmsAttachment($fileInstance, $entropy)
{
/*
if (!entropy.ContainsKey(this.GetInstanceKey(inst)))
{
byte[] entropyData = new byte[256];
random.NextBytes(entropyData);
entropy[this.GetInstanceKey(inst)] = entropyData;
}
string entropy_co = Convert.ToBase64String(entropy[this.GetInstanceKey(inst)]);
string guid = inst.GlobalIdentifier.ToString();
long timestamp = DateTime.Now.Ticks;
string originalFileName = this.GetAttributeValue<string>(inst, KnownAttributeGuids.Text.Name);
string ft_co = String.Format("{0}?oms-attachments/{1}?{2}??{3}", entropy_co, guid, timestamp, originalFileName);
string base64 = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(ft_co));
string safeBase64 = MBS.Framework.Conversion.Base64ToUrlSafeBase64(base64);
return safeBase64;
*/
$entropy_co = base64_encode("lalalala");
//$timestamp = (new \DateTime())->
$timestamp = "112340340";
$originalFileName = "lalala.png";
$ft_co = $entropy_co . "?oms-attachments/" . $fileInstance->GlobalIdentifier . "?" . $timestamp . "??" . $originalFileName;
return base64_encode($ft_co);
}
public function getStackTrace(array $arr)
{
$sr = "";
$ct = count($arr);
for ($i = 0; $i < $ct; $i++)
{
if ($arr[$i] !== null)
{
$sr .= $arr[$i]->InstanceKey->__toString();
}
if ($i < $ct - 1)
{
$sr .= ":";
}
}
return $sr;
}
private function createHtmlLinkToInstanceReference($val)
{
if ($val === null)
{
return "";
}
return "<a href=\"" . System::ExpandRelativePath("~/d/inst/" . $val->InstanceKey . ".htmld") . "\">" . $val->InstanceKey . "</a>";
}
public function getStackTraceWithLinks(array $arr)
{
$sr = "";
$ct = count($arr);
for ($i = 0; $i < $ct; $i++)
{
if ($arr[$i] !== null)
{
$sr .= $this->createHtmlLinkToInstanceReference($arr[$i]);
}
if ($i < $ct - 1)
{
$sr .= ":";
}
}
return $sr;
}
public function getAttachmentUrl(InstanceReference $fileInstance)
{
$entropy = null;
$accessKey = $this->buildAccessKeyForOmsAttachment($fileInstance, $entropy);
return "/" . $this->getTenantName() . "/attachment/" . $fileInstance->InstanceKey . "/" . $accessKey;
}
public function executeReturningAttribute(OmsContext $context, InstanceReference $inst)
{
$value = $this->execute($context, $inst);
if ($value !== null)
{
$val = $context->getWorkData($value);
return $val;
}
return null;
}
public function executeAndEvaluateWorkData(OmsContext $context, InstanceReference $inst)
{
$result = $this->execute($context, $inst);
if ($this->is_a($result, KnownClassGuids::WorkSet))
{
return $context->getWorkData($result);
}
return $result;
}
public function execute(OmsContext $context, InstanceReference $inst, $classesLookupWorkData = true, ?array $parms = null)
{
$instParent = $this->getParentClass($inst);
$methodImplementation = $this->getMethodImplementation($instParent);
if ($methodImplementation !== null)
{
$retval = $methodImplementation->execute($this, $context, $inst, $parms); // $this->executeMethod($context, $inst, $parms);
}
else if ($instParent->GlobalIdentifier->__is_equal(UUID::parse(KnownClassGuids::ReturnAttributeMethodBinding))
|| ($instParent->GlobalIdentifier->__is_equal(UUID::parse(KnownClassGuids::ReturnInstanceSetMethodBinding)))
|| ($instParent->GlobalIdentifier->__is_equal(UUID::parse(KnownClassGuids::ProcessUpdatesMethodBinding))))
{
$methodBindingExecutesMethod = $this->getRelatedInstance($inst, KnownRelationshipGuids::Method_Binding__executes__Method);
if ($methodBindingExecutesMethod === null)
{
echo ("Method Binding.executes Method[" . KnownRelationshipGuids::Method_Binding__executes__Method . "] not found for " . $inst->InstanceKey);die();
}
$parameterAssignments = $this->getRelatedInstances($inst, KnownRelationshipGuids::Method_Binding__has__Parameter_Assignment);
foreach ($parameterAssignments as $parameterAssignment)
{
$this->applyParameterAssignment($context, $parameterAssignment);
}
/*
if (is_array(value: $parms))
{
foreach ($parms as $gid => $value)
{
$context->setWorkData($gid, $value);
}
}
*/
// echo ("MB stack: " . $methodInstance->InstanceKey . ":" . $methodBindingExecutesMethod->InstanceKey);
$retval = $this->execute($context, $methodBindingExecutesMethod, $parms);
}
else if (
// $this->is_a($inst, UUID::parse(KnownClassGuids::TextAttribute))
//|| $this->is_a($inst, UUID::parse(KnownClassGuids::NumericAttribute))
//|| $this->is_a($inst, UUID::parse(KnownClassGuids::DateAttribute))
// || $this->is_a($inst, UUID::parse(KnownClassGuids::BooleanAttribute))
$this->is_a($inst, UUID::parse(KnownClassGuids::WorkSet))
|| ($this->is_a($inst, UUID::parse(KnownClassGuids::Clasz)) && $classesLookupWorkData)
)
{
//return $context->getWorkData($inst);
$retval = $context->getWorkData($inst);
}
else
{
trigger_error("execute: unsupported class '" . $instParent->GlobalIdentifier . "' [" . $instParent->InstanceKey . "]");
$retval = $inst;
}
return $retval;
}
public function applyParameterAssignment(OmsContext $context, InstanceReference $parameterAssignment)
{
$evaluateWorkData = $this->getAttributeValue($parameterAssignment, KnownAttributeGuids::EvaluateWorkSet, false);
$assignsFromWorkData = $this->getRelatedInstance($parameterAssignment, KnownRelationshipGuids::Parameter_Assignment__assigns_from__Executable_returning_Work_Data);
$assignsToParm = $this->getRelatedInstance($parameterAssignment, KnownRelationshipGuids::Parameter_Assignment__assigns_to__Work_Data);
if ($assignsFromWorkData !== null && $assignsToParm !== null)
{
$workData = $this->execute($context, $assignsFromWorkData);
if ($workData !== null)
{
$workDataValue = $context->getWorkData($workData);
// $context->getWorkData($assignsFromWorkData); //
if (
is_string($workDataValue) ||
$this->is_a($workData, KnownClassGuids::WorkSet)
)
{
// !! HACK !!
$workData = $workDataValue;
}
//echo ("update with " . $assignsToParm->InstanceKey . " = " . $workDataValue);
$context->setWorkData($assignsToParm, $workData);
}
else
{
// echo ("setting null on " . $assignsToParm->InstanceKey);
$context->setWorkData($assignsToParm, $assignsFromWorkData);
}
}
}
public function evaluateConditions(OmsContext $context, ?array $trueConditions, ?array $falseConditions)
{
if ($trueConditions !== null)
{
foreach ($trueConditions as $condition)
{
$val = $this->executeReturningAttribute($context, $condition);
if (!$val)
{
return false;
}
}
}
if ($falseConditions !== null)
{
foreach ($falseConditions as $condition)
{
$val = $this->executeReturningAttribute($context, $condition);
if ($val)
{
return false;
}
}
}
return true;
}
public function printWorkData(array $workData)
{
foreach ($workData as $key => $value)
{
echo ($key . " == ");
if ($value instanceof InstanceReference)
{
echo ("[" . $this->createHtmlLinkToInstanceReference($value) . "]");
}
else if (is_array($value))
{
echo("[ ");
foreach ($value as $val)
{
if ($val instanceof InstanceReference)
{
echo ("[" . $this->createHtmlLinkToInstanceReference($value) . "]");
}
else
{
echo ("'" . $val . "'");
}
echo (", ");
}
echo (" ]");
}
else
{
echo ("'" . $value . "'");
}
echo (" ; ");
}
}
public function CompareInstanceSets_ExactMatch(InstanceReference|array|null $left, InstanceReference|array|null $right)
{
//echo ("CIS: " . $left->InstanceKey . " ?? " . $right->InstanceKey);
if ($left === null && $right === null)
return true;
if ($left === null || $right === null)
return false;
if (is_array($left) && is_array($right))
{
// Both are Instance Sets, so we can make some optimizations
if (count($left) !== count($right))
return false;
$is = array_intersect($left, $right);
return count($is) === count($left);
}
else
{
// Instance Set and Instance cannot be compared, for now
if (is_array($left) || is_array($right))
{
return false;
}
}
// If we get here, $left and $right should both be single instances
if ($left->GlobalIdentifier->__is_equal($right->GlobalIdentifier))
{
return true;
}
return false;
}
private function __is_a_impl(InstanceReference $inst, InstanceReference $what, int $reentrant_counter)
{
if ($reentrant_counter > 10)
{
if ($reentrant_counter == 11)
{
echo("recursion detected!\n");
}
echo("__is_a_impl!(" . $inst->InstanceKey . ", " . $what->InstanceKey . ")\n");
if ($reentrant_counter > 30)
{
die();
}
}
$pclass = $this->getParentClass($inst);
if ($pclass === null)
return false;
if ($pclass->__is_equal($what))
{
return true;
}
if (!($pclass->InstanceKey->ClassIndex == 1 && $pclass->InstanceKey->InstanceIndex == 1))
{
$pclassSuperclasses = $this->getRelatedInstances($pclass, KnownRelationshipGuids::Class__has_super__Class);
foreach ($pclassSuperclasses as $pclassSuperclass)
{
if ($what->GlobalIdentifier->__is_equal($pclassSuperclass->GlobalIdentifier))
{
return true;
}
}
}
return false;
}
public function is_a(InstanceReference|string|InstanceKey|array|null $inst, InstanceReference|string|InstanceKey $what)
{
if ($inst === null)
{
return false;
}
if (is_array($inst))
{
return false;
}
$inst = $this->normalizeInstanceReference($inst);
$what = $this->normalizeInstanceReference($what);
return $this->__is_a_impl($inst, $what, 0);
}
public function setSessionAttributeValue(OmsContext $context, InstanceReference $instance, mixed $value)
{
$context->setTemporaryVariable($instance, $value);
}
public function getSessionAttributeValue(OmsContext $context, InstanceReference $instance, mixed $defaultValue = null)
{
return $context->getTemporaryVariable($instance, $defaultValue);
}
}
?>

View File

@ -4,7 +4,7 @@
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Core\InstanceReference;
class MethodBinding

View File

@ -3,7 +3,7 @@
use Mocha\Core\InstanceReference;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Phast\Utilities\Stopwatch;
abstract class MethodImplementation

View File

@ -5,7 +5,7 @@
use Mocha\Core\KnownAttributeGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Oop\MethodImplementation;
use Phast\QuickSort;

View File

@ -5,7 +5,7 @@
use Mocha\Core\KnownAttributeGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Oop\MethodImplementation;
class ConditionalSelectAttributeMethodImplementation extends MethodImplementation

View File

@ -6,7 +6,7 @@
use Mocha\Core\KnownInstanceGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Oop\MethodImplementation;
class ConditionalSelectInstanceSetMethodImplementation extends MethodImplementation

View File

@ -7,7 +7,7 @@
use Mocha\Core\KnownInstanceGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Oms\OmsMetadataException;
use Mocha\Oop\MethodImplementation;
use Phast\UUID;

View File

@ -7,7 +7,7 @@
use Mocha\Core\KnownInstanceGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Oms\OmsMetadataException;
use Mocha\Oop\MethodImplementation;

View File

@ -6,7 +6,7 @@
use Mocha\Core\KnownClassGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Oop\MethodImplementation;
use Phast\UUID;

View File

@ -7,7 +7,7 @@
use Mocha\Core\KnownInstanceGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Oop\MethodImplementation;
use Phast\UUID;

View File

@ -6,7 +6,7 @@
use Mocha\Core\KnownClassGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Oop\MethodImplementation;
use Phast\UUID;

View File

@ -7,7 +7,7 @@
use Mocha\Core\KnownInstanceGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Oms\OmsMetadataException;
use Mocha\Oms\OmsMetadataExceptionSeverity;
use Mocha\Oop\MethodImplementation;
@ -49,6 +49,12 @@
$refIS = $context->getWorkData($refISRel);
if ($refIS !== null)
{
if (is_array($refIS))
{
// ! FIXME: we should not be getting a Multi Instance here
$refIS = $refIS[0];
}
$pc = $oms->getParentClass($refIS);
if ($pc !== null)
{

View File

@ -7,7 +7,7 @@
use Mocha\Core\KnownInstanceGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Oms\OmsMetadataException;
use Mocha\Oms\OmsMetadataExceptionSeverity;
use Mocha\Oop\MethodImplementation;

View File

@ -6,7 +6,7 @@
use Mocha\Core\KnownClassGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Oop\MethodImplementation;
use Phast\UUID;

View File

@ -6,7 +6,7 @@
use Mocha\Core\KnownClassGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Oms\OmsMetadataException;
use Mocha\Oop\MethodImplementation;

View File

@ -7,7 +7,7 @@
use Mocha\Core\KnownInstanceGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Oms\OmsMetadataException;
use Mocha\Oms\OmsMetadataExceptionSeverity;
use Mocha\Oop\MethodImplementation;

View File

@ -11,11 +11,12 @@
require("core/KnownMethodBindingGuids.inc.php");
require("core/OmsContext.inc.php");
require("core/Oms.inc.php");
require("oms/OmsMetadataException.inc.php");
require("oms/Oms.inc.php");
require("oms/DatabaseOms.inc.php");
require("oms/MySQLDatabaseOms.inc.php");
require("oms/HttpOmsClient.inc.php");
require("oop/MethodImplementation.inc.php");
require("oop/MethodBinding.inc.php");
@ -37,6 +38,7 @@
require("ui/renderers/html/Editor.inc.php");
require("ui/renderers/html/HTMLRenderer.inc.php");
require("ui/renderers/html/HTMLRenderer2.inc.php");
require("ui/tasks/Task.inc.php");
require("ui/tasks/HardcodedTask.inc.php");

View File

@ -10,9 +10,6 @@
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\OmsContext;
use Mocha\Oms\Oms;
use Mocha\Oms\MySQLDatabaseOms;
use Mocha\Oms\OmsMetadataException;
use Mocha\Oms\OmsMetadataExceptionSeverity;
use Mocha\UI\Controls\InstanceBrowser;
@ -75,7 +72,7 @@
public bool $IncludeTopNavigationBar;
public ?Oms $OMS;
public ?\Mocha\Core\Oms $OMS;
public function __construct(OmsContext $context, bool $withoutOms = false)
{
@ -103,7 +100,7 @@
public function registerEditors()
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = $this->OMS;
if ($oms == null) return;
@ -316,7 +313,7 @@
public function renderTaskStep2(&$parentElementContents, InstanceReference $usesElement)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -329,7 +326,7 @@
$workDataRelatedInstance = $this->Context->getWorkData(KnownInstanceGuids::WorkSet__RelatedInstance);
if ($workDataRelatedInstance !== null)
{
$this->TargetInstance = $oms->getInstanceByKey(InstanceKey::Parse($workDataRelatedInstance));
$this->TargetInstance = $oms->getInstanceByKey(InstanceKey::parse($workDataRelatedInstance));
}
$this->renderBeginPage();
@ -347,7 +344,7 @@
public function renderTask(InstanceReference $task, ?InstanceReference $relatedInstance = null)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
$taskName = $oms->getAttributeValue($task, KnownAttributeGuids::Name);
@ -491,7 +488,7 @@ EOF
private function updateWorkDataWithElementContents(array $parentElementContents, InstanceReference $element, $singular = true, $i = 0)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -529,7 +526,7 @@ EOF
}
else
{
$ik = InstanceKey::Parse($value);
$ik = InstanceKey::parse($value);
if ($ik === null)
{
echo ("invalid ik: " . $value);
@ -539,12 +536,12 @@ EOF
}
}
echo ("updateWorkDataWithElementContents: setting work data `" . $ecInst->InstanceKey . "` from EC `" . $ecid . "` to value '" . $value_str . "'<br />");
// echo ("updateWorkDataWithElementContents: setting work data `" . $ecInst->InstanceKey . "` from EC `" . $ecid . "` to value '" . $value_str . "'<br />");
$this->Context->setWorkData($ecInst, $value);
}
else
{
echo ("updateWorkDataWithElementContents: not setting work data `" . $ecInst->InstanceKey . "` from EC `" . $ecid . "`, not present in POST<br />");
// echo ("updateWorkDataWithElementContents: not setting work data `" . $ecInst->InstanceKey . "` from EC `" . $ecid . "`, not present in POST<br />");
}
}
@ -556,7 +553,7 @@ EOF
public function updateElementContentInstance(array &$parentElementContents, $targetInstance, $relatedECInst, $value)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -645,7 +642,7 @@ EOF
private function updateElement(&$parentElementContents, $targetInstance, $element)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -901,7 +898,7 @@ EOF
private function checkValidationsForElement(array $parentElementContents, $element)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -910,6 +907,7 @@ EOF
{
$ecid = "ec_" . $this->getElementContentId($parentElementContents, $relatedEC);
$value = null;
echo ("checking POST " . $ecid . " (" . $_POST[$ecid] . ")");
if (isset($_POST[$ecid]))
{
$value = $_POST[$ecid];
@ -925,7 +923,7 @@ EOF
private function processRelatedPostback(array &$parentElementContents, InstanceReference $element)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -999,7 +997,7 @@ EOF
{
if (isset($_POST["target_inst_id"]))
{
$targetInstance = $oms->getInstanceByKey(InstanceKey::Parse($_POST["target_inst_id"]));
$targetInstance = $oms->getInstanceByKey(InstanceKey::parse($_POST["target_inst_id"]));
$this->TargetInstance = $targetInstance;
}
}
@ -1020,7 +1018,9 @@ EOF
}
if ($hasFailedValidations)
{
return false;
}
$this->updateWorkDataWithElementContents($parentElementContents, $element);
@ -1042,7 +1042,7 @@ EOF
public function processPostback(InstanceReference $element)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -1091,7 +1091,7 @@ EOF
private function checkValidationsForElementContent(array $parentElementContents, InstanceReference $elementContent, ?string $value)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -1165,7 +1165,7 @@ EOF
public function elementContentIsEmpty(InstanceReference $elementContent) : bool
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
/**
@ -1233,7 +1233,7 @@ EOF
public function shouldRenderElementContentLabel(InstanceReference $elementContent)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -1265,7 +1265,7 @@ EOF
public function shouldRenderElementContent(InstanceReference $elementContent)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
if ($this->Context->getElementParm($elementContent, "visible", false))
@ -1275,10 +1275,14 @@ EOF
$displayOptions = $oms->getRelatedInstances($elementContent, $oms->getInstanceByGlobalIdentifier(KnownRelationshipGuids::Element_Content__has__Element_Content_Display_Option));
if ($oms->instanceSetContains($displayOptions, $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::DisplayOption__DoNotShow)))
{
// echo (" ! has Do Not Show ");
return false;
}
if (!$this->Context->getElementParm($elementContent, "visible", true))
{
// echo ( " ! has override element parm Visible = False");
return false;
}
@ -1288,7 +1292,7 @@ EOF
public function buildStyleAttribute(bool $isBlockElement, array $constantStyles, array $stylesFromInstanceSet)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -1375,7 +1379,7 @@ EOF
public function renderElementContent(array &$parentElementContents, InstanceReference $elementContent, $renderNotEnterable = false)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -1726,7 +1730,7 @@ EOF
public function getElementContentValue(InstanceReference $elementContent, $defaultValue = null)
{
print_r($_POST);
echo ("get post val " . $elementContent->InstanceKey); die();
echo ("get post val " . $elementContent->InstanceKey); //die();
if (isset($_POST["ec_" . $elementContent->InstanceKey]))
{
return $_POST["ec_" . $elementContent->InstanceKey];
@ -1741,7 +1745,7 @@ EOF
public function getEditor(InstanceReference $ecInst)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -1758,7 +1762,7 @@ EOF
public function renderExecutableReturningAttribute(array &$parentElementContents, InstanceReference $elementContent, InstanceReference $ecInst, ?InstanceReference $relatedInstance, $renderNotEnterable = false)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -1846,7 +1850,7 @@ EOF
public function renderTextAttributeEC(array $parentElementContents, InstanceReference $ec, InstanceReference $inst, $password = false, $value = null)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -1886,7 +1890,7 @@ EOF
public function renderBooleanAttributeEC(array $parentElementContents, InstanceReference $ec, InstanceReference $inst, $value = null)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -1926,7 +1930,7 @@ EOF
public function renderNumericAttributeEC(array $parentElementContents, InstanceReference $ec, InstanceReference $inst, $password = false, $value = null)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -1957,7 +1961,7 @@ EOF
public function renderRichTextAttributeEC(array $parentElementContents, InstanceReference $ec, InstanceReference $inst, $value = null)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -2027,7 +2031,7 @@ EOF
public function renderBeginPage($title = "")
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = $this->OMS;
if ($oms !== null)
@ -2197,7 +2201,7 @@ EOF
public function renderEndPage()
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = $this->OMS;
@ -2278,7 +2282,7 @@ EOF
public function renderInitialElement(InstanceReference $element)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -2310,7 +2314,7 @@ EOF
$this->renderEndPage();
}
private function renderEndForm($allElementsAreReadonly = false)
public function renderEndForm($allElementsAreReadonly = false)
{
if (!$allElementsAreReadonly)
{
@ -2370,7 +2374,7 @@ EOF
private function get__EC_Override_Label_or_default_Instance_Title(array $parms)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -2405,7 +2409,7 @@ EOF
private function getSubelementInstances(InstanceReference $parentElementContent)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -2453,7 +2457,7 @@ EOF
public function renderElement(array &$parentElementContents, InstanceReference $element, array $displayOptions, $renderNotEnterable = false)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -2513,19 +2517,24 @@ EOF
$ecInst0 = $oms->getRelatedInstance($contents[0], KnownRelationshipGuids::Element_Content__has__Instance);
if ($ecInst0 !== null)
{
// echo ("Element Content.has Instance returned " . $ecInst0->GlobalIdentifier . " for " . $contents[0]->GlobalIdentifier);
$wd = $this->Context->getWorkData($ecInst0);
if ($wd !== null)
{
$this->Context->setWorkData(KnownInstanceGuids::WorkSet__RelatedInstance, $wd);
}
}
else
{
echo ("Element Content.has Instance returned NULL for " . $contents[0]->GlobalIdentifier);
}
}
$qs = new QuickSort();
$sortedElementContents = $qs->Sort_By($contents, function($item)
{
/**
* @var MySQLDatabaseOms
* @var \Mocha\Core\Oms
*/
$oms = mocha_get_oms();
@ -2533,18 +2542,24 @@ EOF
return $order;
});
// echo ("sorted elem contents count: " . count($sortedElementContents));
foreach ($sortedElementContents as $elementContent)
{
if ($elementContent === null)
{
// echo ("ec is null ! ");
continue;
}
if (!$this->shouldRenderElementContent($elementContent))
{
// echo ("not rendering ec " . $elementContent->GlobalIdentifier . " cuz reasons");
continue;
}
// echo ("ec rendering " . $elementContent->GlobalIdentifier);
$ecDisplayOptions = $oms->getRelatedInstances($elementContent, KnownRelationshipGuids::Element_Content__has__Element_Content_Display_Option);
$ecInst = $oms->getRelatedInstance($elementContent, KnownRelationshipGuids::Element_Content__has__Instance);
$mcx_classes = [ "mcx-elementcontent", "uwt-formview-item" ];

View File

@ -0,0 +1,135 @@
<?php
namespace Mocha\UI\Renderers\HTML;
use Mocha\Core\OmsContext;
use Phast\System;
class HTMLRenderer2 extends HTMLRenderer
{
public function __construct(OmsContext $context, bool $withoutOms = false)
{
parent::__construct($context, $withoutOms);
}
public function renderInitialElement($element)
{
$json = $this->OMS->getResponse($element);
$this->renderResponse($json["value"]);
}
public function renderResponse(array $json)
{
$this->renderBeginPage("Test App");
$this->renderBeginContent();
$this->renderFragment($json);
$this->renderEndContent();
$this->renderEndForm();
$this->renderEndPage();
}
public function renderFragment(array $json, $fqecidPrefix = "")
{
$fqecid = $fqecidPrefix . $json["ecid"];
if ($json["visible"] === false)
{
return;
}
if ($json["widget"] == "root")
{
$this->renderFragment($json["body"]);
}
else if ($json["widget"] == "vbox")
{
echo ("<div class=\"uwt-layout-box uwt-orientation-vertical\">");
foreach ($json["children"] as $child)
{
$this->renderFragment($child);
}
echo ("</div>");
}
else if ($json["widget"] == "image")
{
echo ("<div class=\"uwt-image\" style=\"background-image: url('" . System::ExpandRelativePath("~/attachment/" . $json["iid"] . "/" . $json["target"]) . "');");
if (isset($json["width"]))
{
echo(" width: " . $json["width"] . ";");
}
if (isset($json["height"]))
{
echo(" height: " . $json["height"] . ";");
}
if (isset($json["horizontalAlignment"]) && $json["horizontalAlignment"] == "center")
{
echo(" margin-left: auto; margin-right: auto;");
}
echo("\">&nbsp;</div>");
}
else if ($json["widget"] == "fieldSet")
{
echo ("<div class=\"uwt-formview mcx-element\" data-instance-id=\"" . $json["iid"] . "\" data-ecid=\"" . $fqecid . "\">");
foreach ($json["children"] as $child)
{
$fqecidChild = $fqecidPrefix . $child["ecid"];
echo ("<div class=\"uwt-formview-item mcx-elementcontent");
if (!isset($child["label"]))
{
echo(" uwt-hide-label");
}
if (!isset($child["enabled"]) || $child["enabled"] == true)
{
echo(" mcx-editable");
}
if (isset($child["required"]) && $child["required"] == true)
{
echo(" mcx-required");
}
echo ("\" data-instance-id=\"" . $child["iid"] . "\" data-ecid=\"" . $child["ecid"] . "\">");
echo ("<div class=\"uwt-formview-item-label\">");
echo ("<label for=\"ec_" . $fqecidChild . "\">");
echo ($child["label"]);
echo ("</label>");
echo ("</div>");
echo ("<div class=\"uwt-formview-item-content\"");
/*
if (!isset($child["label"]))
{
echo(" colspan=\"2\"");
}
*/
echo (">");
$this->renderFragment($child, $fqecid . ":");
echo ("</div>");
echo ("</div>");
}
echo ("</div>");
}
else if ($json["widget"] == "text")
{
if ($json["enabled"] === false)
{
echo ("<p data-ecid=\"" . $json["ecid"] . "\">" . $json["value"] . "</p>");
}
else
{
echo ("<input id=\"ec_" . $fqecid . "\" name=\"ec_" . $fqecid . "\" type=\"text\" value=\"" . $json["value"] . "\"");
if (isset($json["maximumLength"]))
{
echo ("maxlength=\"" . $json["maximumLength"] . "\"");
}
echo (" />");
}
}
else if ($json["widget"] == "obscuredText")
{
echo ("<input id=\"ec_" . $fqecid . "\" name=\"ec_" . $fqecid . "\" type=\"password\" value=\"" . $json["value"] . "\" />");
}
}
}
?>

View File

@ -198,3 +198,11 @@ body > div.uwt-page-content
{
padding: 16px;
}
a.uwt-external-link::after
{
content: "\f08e";
font-family: "Font Awesome 6 Pro";
padding-left: 8px;
font-weight: 300;
}

View File

@ -37,7 +37,7 @@
$instId = $this->Page->GetPathVariableValue("instid");
$accessKey = $this->Page->GetPathVariableValue("accesskey");
$inst = $oms->getInstanceByKey(InstanceKey::Parse($instId));
$inst = $oms->getInstanceByKey(InstanceKey::parse($instId));
$ext = "jpg";
$contentType = $oms->getAttributeValue($inst, KnownAttributeGuids::ContentType);

View File

@ -3,7 +3,7 @@
namespace Mocha\UI\Pages;
use Mocha\Core\KnownAttributeGuids;
use Mocha\Oms\Oms;
use Mocha\Core\Oms;
use Mocha\Core\InstanceKey;
use Mocha\Core\InstanceReference;
use Mocha\Core\KnownClassGuids;
@ -98,7 +98,7 @@
$parentECIDs = substr($fqecid, 0, strripos($fqecid, ":"));
$ec = $oms->getInstanceByKey(InstanceKey::Parse($ecid));
$ec = $oms->getInstanceByKey(InstanceKey::parse($ecid));
if ($ec === null)
{
header ("HTTP/1.1 404 Not Found");

View File

@ -10,6 +10,7 @@
use Mocha\Core\OmsContext;
use Mocha\UI\Renderers\HTML\HTMLRenderer;
use Mocha\UI\Renderers\HTML\HTMLRenderer2;
use Phast\RenderingEventArgs;
use Phast\System;
use Phast\WebPage;
@ -33,8 +34,6 @@
$context = new OmsContext();
$renderer = new HTMLRenderer($context);
$pageElement = $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::Element__HomePage);
if ($pageElement === null)
{
@ -42,11 +41,14 @@
die();
}
// $renderer = new HTMLRenderer($context);
$renderer = new HTMLRenderer2($context);
$renderer->IsPostback = $this->Page->IsPostback;
if ($this->Page->IsPostback)
{
$renderer->processPostback($pageElement);
}
$renderer->renderInitialElement($pageElement);
exit();

View File

@ -26,9 +26,9 @@
*/
$oms = mocha_get_oms();
$instkey = InstanceKey::Parse($this->Page->GetPathVariableValue("instid"));
$instkey = InstanceKey::parse($this->Page->GetPathVariableValue("instid"));
$castkey = InstanceKey::Parse($this->Page->GetPathVariableValue("castinstid"));
$castkey = InstanceKey::parse($this->Page->GetPathVariableValue("castinstid"));
$inst = $oms->getInstanceByKey($instkey);
if ($inst === null)

View File

@ -7,16 +7,17 @@
use Mocha\Core\KnownMethodBindingGuids;
use Mocha\Core\KnownRelationshipGuids;
use Mocha\Core\Oms;
use Mocha\Core\OmsContext;
use Mocha\UI\Renderers\HTML\HTMLRenderer;
use Mocha\UI\Renderers\HTML\HTMLRenderer2;
use Phast\CancelEventArgs;
use Phast\EventArgs;
use Phast\RenderingEventArgs;
use Phast\System;
use Phast\WebPage;
use Mocha\Oms\MySQLDatabaseOms;
class LoginPage extends WebPage
{
protected function OnInitializing(CancelEventArgs $e)
@ -31,7 +32,6 @@
exit();
}
$oms->setTenant($tenant);
$oms->initializeInstanceCache();
// echo (" login token: " . $_SESSION["user_token_" . $oms->getTenant()->ID]);
@ -83,12 +83,126 @@
parent::OnRendering($re);
/**
* @var MySQLDatabaseOms
* @var Oms
*/
$oms = mocha_get_oms();
$pageElement = $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::Element__LoginPage);
if ($pageElement === null)
{
print ("could not find element 'LoginPage'");
die();
}
// _flowExecutionKey=e1s1&1233/wd:Select_All=1&_eventId_validate=1233%2Fwd%3ASelect_All&sessionSecureToken=4735eafa-da24-4566-b7b2-196719eca3ed&clientRequestID=405dd7011a41450792b5af6a219f39e7
// $response = $oms->processElement($pageElement);
$context = $oms->createContext();
$renderer = new HTMLRenderer2($context);
$renderer->IncludeTopNavigationBar = false;
$json = $oms->getResponse($pageElement);
$json = $json["value"];
$renderer->ProcessUpdatesFunction = function($sender, $element)
{
/**
* @var Oms
*/
$oms = mocha_get_oms();
$ec_UserName = $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::ElementContent__UserNameForLoginPage);
$ecinst_UserName = $oms->getRelatedInstance($ec_UserName, KnownRelationshipGuids::Element_Content__has__Instance);
$ec_Password = $oms->getInstanceByGlobalIdentifier(KnownInstanceGuids::ElementContent__PasswordForLoginPage);
$ecinst_Password = $oms->getRelatedInstance($ec_Password, KnownRelationshipGuids::Element_Content__has__Instance);
// $ct = $oms->getRelatedInstance($element, $oms->getInstanceByGlobalIdentifier(KnownRelationshipGuids::Element__processed_by__Control_Transaction_Method));
// Login Page@ Login Page Edit(CT)*S
// uses Build Response Method Binding...
//
$userName = $sender->Context->getWorkData($ecinst_UserName); // $_POST["ec_56$4"];
$password = $sender->Context->getWorkData($ecinst_Password); // $_POST["ec_56$5"];
$mbUser__get__User_for_User_Name_parm = $oms->getInstanceByGlobalIdentifier(KnownMethodBindingGuids::User__get__User_for_User_Name_parm);
if ($mbUser__get__User_for_User_Name_parm === null)
{
echo("`User@get User for User Name parm`: method not found ('" . KnownMethodBindingGuids::User__get__User_for_User_Name_parm . "')");die();
}
$instUser = $oms->execute($sender->Context, $mbUser__get__User_for_User_Name_parm);
$instUser = $sender->Context->getWorkData($instUser);
if ($instUser !== null)
{
$passwordSalt = $oms->getAttributeValue($instUser, $oms->getInstanceByGlobalIdentifier(KnownAttributeGuids::PasswordSalt));
$passwordHashExpected = $oms->getAttributeValue($instUser, $oms->getInstanceByGlobalIdentifier(KnownAttributeGuids::PasswordHash));
$passwordHashActual = hash('sha512', $password . $passwordSalt);
if ($passwordHashExpected == $passwordHashActual)
{
$token = $this->random_str();
// create the instance of `System Account Signon`
$instLogin = $oms->createInstanceOf($oms->getInstanceByGlobalIdentifier(KnownClassGuids::UserLogin));
if ($instLogin !== null)
{
// FIXME: these attribute should be defined in the Mocha/ZQ
// FIXME: they should be wrapped in a conditional which checks if we are serving in a GDPR compliant region
// should we be storing this information then? probably not...
$oms->setAttributeValue($instLogin, KnownAttributeGuids::Token, $token);
$oms->setAttributeValue($instLogin, KnownAttributeGuids::IPAddress, $_SERVER["REMOTE_ADDR"]);
$oms->assignRelationship($instLogin, $oms->getInstanceByGlobalIdentifier(KnownRelationshipGuids::User_Login__has__User), $instUser);
}
else
{
echo ("could not create login token");
die();
}
$_SESSION["user_token_" . $oms->getTenant()->ID] = $token;
$oms->setCurrentUser($instUser);
System::RedirectFromLoginPage();
exit();
}
else
{
//$this->Page->GetControlByID("literal1")->EnableRender = true;
//System::RedirectToLoginPage(true);
echo ("invalid user name or password");
die();
}
}
$ecPasswordMsg = $oms->getInstanceByGlobalIdentifier("684f1e039ecd43d58acadcf5b84c71f8");
$sender->Context->setElementParm($ecPasswordMsg, "visible", true);
};
$renderer->IsPostback = $this->Page->IsPostback;
$renderer->StyleClasses[] = "mcx-loginpage";
if ($this->Page->IsPostback)
{
$renderer->processPostback($pageElement);
}
$renderer->SubmitButtonText = "Log In";
$renderer->renderResponse($json);
$re->Cancel = true;
$re->Handled = true;
exit();
}
protected function OnRendering2(RenderingEventArgs $re)
{
parent::OnRendering($re);
/**
* @var Oms
*/
$oms = mocha_get_oms();
//mocha_init_spot_timer($this);
$path = System::GetVirtualPath();
$tenantName = "";
if ($path[0] == "madi")
@ -119,7 +233,7 @@
$renderer->ProcessUpdatesFunction = function($sender, $element)
{
/**
* @var MySQLDatabaseOms
* @var Oms
*/
$oms = mocha_get_oms();

View File

@ -105,7 +105,7 @@
{
if ($cmdparts[0] === "instance")
{
$ik = InstanceKey::Parse($cmdparts[1]);
$ik = InstanceKey::parse($cmdparts[1]);
if ($ik === null)
{
header("HTTP/1.1 404 Not Found");

View File

@ -43,7 +43,7 @@
$search = new SearchHelper($oms);
$ec = $oms->getInstanceByKey(InstanceKey::Parse($id));
$ec = $oms->getInstanceByKey(InstanceKey::parse($id));
if ($ec !== null)
{
$ecinst = $oms->getRelatedInstance($ec, KnownRelationshipGuids::Element_Content__has__Instance);

View File

@ -30,7 +30,7 @@
$tenant = $this->Page->GetPathVariableValue("tenant");
$iid = $this->Page->GetPathVariableValue("instid");
$inst = $oms->getInstanceByKey(InstanceKey::Parse($iid));
$inst = $oms->getInstanceByKey(InstanceKey::parse($iid));
$instParent = $oms->getParentClass($inst);
$tasks = $oms->getRelatedTasks($inst);
@ -156,7 +156,7 @@
$tenant = $this->Page->GetPathVariableValue("tenant");
$iid = $this->Page->GetPathVariableValue("instid");
$inst = $oms->getInstanceByKey(InstanceKey::Parse($iid));
$inst = $oms->getInstanceByKey(InstanceKey::parse($iid));
$instParent = $oms->getParentClass($inst);
$tasks = $oms->getRelatedTasks($inst);

View File

@ -22,8 +22,8 @@
*/
$oms = mocha_get_oms();
$instanceKey = InstanceKey::Parse($this->Page->GetPathVariableValue("instid"));
$relatedTaskKey = InstanceKey::Parse($this->Page->GetPathVariableValue("reltaskid"));
$instanceKey = InstanceKey::parse($this->Page->GetPathVariableValue("instid"));
$relatedTaskKey = InstanceKey::parse($this->Page->GetPathVariableValue("reltaskid"));
$instance = $oms->getInstanceByKey($instanceKey);
$relatedTaskInstance = $oms->getInstanceByKey($relatedTaskKey);

View File

@ -313,7 +313,7 @@ EOF
<td></td>
<td></td>
<td></td>
<td>Default Tenant</td>
<td><?php echo($values["tenant_purpose"]); ?></td>
</tr>
<?php
}

View File

@ -25,7 +25,7 @@
$query = $_GET["q"];
$inst = null;
if (InstanceKey::TryParse($query, $inst))
if (InstanceKey::tryParse($query, $inst))
{
System::Redirect("~/d/inst/1\$" . $inst->ClassIndex . "/" . $inst->__toString() . ".htmld");
$re->Handled = true;

View File

@ -21,7 +21,7 @@
*/
$oms = mocha_get_oms();
$taskKey = InstanceKey::Parse($this->Page->GetPathVariableValue("instid"));
$taskKey = InstanceKey::parse($this->Page->GetPathVariableValue("instid"));
$taskInstance = $oms->getInstanceByKey($taskKey);
$initiatingElement = $oms->getRelatedInstance($taskInstance, KnownRelationshipGuids::Task__has_initiating__Element);