Merge remote-tracking branch 'origin/support/3.2' into develop

This commit is contained in:
Eric Espie
2024-05-21 14:30:30 +02:00
7 changed files with 826 additions and 45 deletions

View File

@@ -4272,43 +4272,6 @@ class AttributeEncryptedString extends AttributeString implements iAttributeNoGr
{
const SEARCH_WIDGET_TYPE = self::SEARCH_WIDGET_TYPE_RAW;
static $sKey = null; // Encryption key used for all encrypted fields
static $sLibrary = null; // Encryption library used for all encrypted fields
public function __construct($sCode, $aParams)
{
parent::__construct($sCode, $aParams);
if (self::$sKey == null)
{
self::$sKey = MetaModel::GetConfig()->GetEncryptionKey();
}
if (self::$sLibrary == null)
{
self::$sLibrary = MetaModel::GetConfig()->GetEncryptionLibrary();
}
}
/**
* When the attribute definitions are stored in APC cache:
* 1) The static class variable $sKey is NOT serialized
* 2) The object's constructor is NOT called upon wakeup
* 3) mcrypt may crash the server if passed an empty key !!
*
* So let's restore the key (if needed) when waking up
**/
public function __wakeup()
{
if (self::$sKey == null)
{
self::$sKey = MetaModel::GetConfig()->GetEncryptionKey();
}
if (self::$sLibrary == null)
{
self::$sLibrary = MetaModel::GetConfig()->GetEncryptionLibrary();
}
}
protected function GetSQLCol($bFullSpec = false)
{
return "TINYBLOB";
@@ -4347,8 +4310,8 @@ class AttributeEncryptedString extends AttributeString implements iAttributeNoGr
*/
public function FromSQLToValue($aCols, $sPrefix = '')
{
$oSimpleCrypt = new SimpleCrypt(self::$sLibrary);
$sValue = $oSimpleCrypt->Decrypt(self::$sKey, $aCols[$sPrefix]);
$oSimpleCrypt = new SimpleCrypt(MetaModel::GetConfig()->GetEncryptionLibrary());
$sValue = $oSimpleCrypt->Decrypt(MetaModel::GetConfig()->GetEncryptionKey(), $aCols[$sPrefix]);
return $sValue;
}
@@ -4363,8 +4326,8 @@ class AttributeEncryptedString extends AttributeString implements iAttributeNoGr
*/
public function GetSQLValues($value)
{
$oSimpleCrypt = new SimpleCrypt(self::$sLibrary);
$encryptedValue = $oSimpleCrypt->Encrypt(self::$sKey, $value);
$oSimpleCrypt = new SimpleCrypt(MetaModel::GetConfig()->GetEncryptionLibrary());
$encryptedValue = $oSimpleCrypt->Encrypt(MetaModel::GetConfig()->GetEncryptionKey(), $value);
$aValues = array();
$aValues[$this->Get("sql")] = $encryptedValue;
@@ -11315,6 +11278,10 @@ class AttributeEnumSet extends AttributeSet
}
return $aValues;
}
public function Equals($val1, $val2)
{
return $val1->Equals($val2);
}
}

View File

@@ -385,7 +385,7 @@ class ormSet
*/
public function Equals(ormSet $other)
{
return implode(', ', $this->GetValue()) === implode(', ', $other->GetValue());
return implode(', ', $this->GetValues()) === implode(', ', $other->GetValues());
}
/**

View File

@@ -537,7 +537,7 @@ EOF
}
else
{
throw new Exception('graphviz not found (executable path: '.$sDotExecutable.')');
throw new Exception('graphviz not found');
}
return $sHtml;
}
@@ -592,7 +592,7 @@ EOF
}
else
{
throw new Exception('graphviz not found (executable path: '.$sDotExecutable.')');
throw new Exception('graphviz not found');
}
return $sHtml;
}

View File

@@ -25,7 +25,9 @@ EOF;
exit(-1);
}
/////////////////////////////////////////////////
if (! utils::IsModeCLI())
$sCleanName = strtolower(trim(PHP_SAPI));
if ($sCleanName !== 'cli')
{
echo "Mode CLI only";
exit(-1);

View File

@@ -129,6 +129,13 @@ abstract class ItopDataTestCase extends ItopTestCase
{
$this->CreateTestOrganization();
}
$oConfig = MetaModel::GetConfig();
if ($oConfig->GetEncryptionLibrary() != DEFAULT_ENCRYPTION_LIB
&& $oConfig->GetEncryptionKey() == DEFAULT_ENCRYPTION_KEY) {
// Config file is corrupted, let's fix it
$oConfig->SetEncryptionKey("6eb9d9afa3ee0fbcebe622a33bf57aaeafb7c37998fd24c403c2522c2d60117f");
}
}
/**

View File

@@ -0,0 +1,608 @@
<?xml version="1.0" encoding="UTF-8"?>
<itop_design xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.7">
<classes>
<class id="TestAbstract" _delta="define">
<parent>cmdbAbstractObject</parent>
<properties>
<category>bizmodel,searchable</category>
<abstract>true</abstract>
<db_table>testabstract</db_table>
<reconciliation>
<attributes>
<attribute id="finalclass"/>
<attribute id="name"/>
</attributes>
</reconciliation>
<naming>
<attributes>
<attribute id="name"/>
</attributes>
</naming>
</properties>
<fields>
<field id="name" xsi:type="AttributeString">
<sql>name</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
<validation_pattern/>
<tracking_level>all</tracking_level>
</field>
<field id="meta_enum" xsi:type="AttributeMetaEnum">
<values>
<value id="open">open</value>
<value id="terminated">terminated</value>
</values>
<sql>meta_enum</sql>
<default_value>open</default_value>
<tracking_level>all</tracking_level>
<mappings>
<mapping id="TestObject">
<attcode>status</attcode>
<metavalues>
<metavalue id="terminated">
<values>
<value id="cancel"/>
<value id="done"/>
</values>
</metavalue>
</metavalues>
</mapping>
</mappings>
</field>
</fields>
<presentation/>
<methods/>
</class>
<class id="TestObject" _delta="define">
<parent>TestAbstract</parent>
<properties>
<category>bizmodel,searchable</category>
<abstract>false</abstract>
<db_table>testobject</db_table>
<uniqueness_rules>
<rule id="unique_name">
<attributes>
<attribute id="name"/>
</attributes>
<filter><![CDATA[]]></filter>
<disabled>false</disabled>
<is_blocking>false</is_blocking>
</rule>
</uniqueness_rules>
<reconciliation>
<attributes>
<attribute id="name"/>
<attribute id="org_id"/>
</attributes>
</reconciliation>
<naming>
<attributes>
<attribute id="name"/>
</attributes>
</naming>
<indexes _delta="define">
<index id="caselog" _delta="define">
<attributes>
<attribute id="caselog"/>
</attributes>
</index>
<index id="enumset" _delta="define">
<attributes>
<attribute id="enumset"/>
</attributes>
</index>
<index id="tagset" _delta="define">
<attributes>
<attribute id="tagset"/>
</attributes>
</index>
<index id="parent_id" _delta="define">
<attributes>
<attribute id="parent_id"/>
</attributes>
</index>
<index id="email" _delta="define">
<attributes>
<attribute id="email"/>
</attributes>
</index>
<index id="html" _delta="define">
<attributes>
<attribute id="html"/>
</attributes>
</index>
<index id="integer" _delta="define">
<attributes>
<attribute id="integer"/>
</attributes>
</index>
<index id="percentage" _delta="define">
<attributes>
<attribute id="percentage"/>
</attributes>
</index>
<index id="decimal" _delta="define">
<attributes>
<attribute id="decimal"/>
</attributes>
</index>
<index id="ip_address" _delta="define">
<attributes>
<attribute id="ip_address"/>
</attributes>
</index>
<index id="url" _delta="define">
<attributes>
<attribute id="url"/>
</attributes>
</index>
<index id="encrypted" _delta="define">
<attributes>
<attribute id="encrypted"/>
</attributes>
</index>
<index id="deadline" _delta="define">
<attributes>
<attribute id="deadline"/>
</attributes>
</index>
<index id="long_text" _delta="define">
<attributes>
<attribute id="long_text"/>
</attributes>
</index>
<index id="duration" _delta="define">
<attributes>
<attribute id="duration"/>
</attributes>
</index>
<index id="enum" _delta="define">
<attributes>
<attribute id="enum"/>
</attributes>
</index>
<index id="date_time" _delta="define">
<attributes>
<attribute id="date_time"/>
</attributes>
</index>
<index id="oql" _delta="define">
<attributes>
<attribute id="oql"/>
</attributes>
</index>
<index id="boolean" _delta="define">
<attributes>
<attribute id="boolean"/>
</attributes>
</index>
</indexes>
</properties>
<fields>
<field id="org_id" xsi:type="AttributeExternalKey">
<sql>org_id</sql>
<filter/>
<dependencies/>
<is_null_allowed>false</is_null_allowed>
<target_class>Organization</target_class>
<on_target_delete>DEL_AUTO</on_target_delete>
<tracking_level>all</tracking_level>
</field>
<field id="parent_id" xsi:type="AttributeHierarchicalKey">
<sql>parent_id</sql>
<filter/>
<dependencies/>
<is_null_allowed>true</is_null_allowed>
<on_target_delete>DEL_AUTO</on_target_delete>
<tracking_level>all</tracking_level>
</field>
<field id="caselog" xsi:type="AttributeCaseLog">
<sql>caselog</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
<tracking_level>all</tracking_level>
</field>
<field id="date" xsi:type="AttributeDate">
<sql>date</sql>
<default_value>2010-05-26</default_value>
<is_null_allowed>true</is_null_allowed>
<tracking_level>all</tracking_level>
</field>
<field id="date_time" xsi:type="AttributeDateTime">
<sql>date_time</sql>
<default_value>2000-01-01 00:00:00</default_value>
<is_null_allowed>true</is_null_allowed>
<tracking_level>all</tracking_level>
</field>
<field id="deadline" xsi:type="AttributeDeadline">
<sql>deadline</sql>
<default_value>2028-05-26 00:00:00</default_value>
<is_null_allowed>true</is_null_allowed>
<tracking_level>all</tracking_level>
</field>
<field id="decimal" xsi:type="AttributeDecimal">
<sql>decimal</sql>
<default_value>1.01</default_value>
<is_null_allowed>false</is_null_allowed>
<digits>8</digits>
<decimals>2</decimals>
<tracking_level>all</tracking_level>
</field>
<field id="duration" xsi:type="AttributeDuration">
<sql>duration</sql>
<default_value>180</default_value>
<is_null_allowed>false</is_null_allowed>
<tracking_level>all</tracking_level>
</field>
<field id="email" xsi:type="AttributeEmailAddress">
<sql>email</sql>
<default_value>test@combodo.com</default_value>
<is_null_allowed>false</is_null_allowed>
<validation_pattern/>
<tracking_level>all</tracking_level>
</field>
<field id="encrypted" xsi:type="AttributeEncryptedString">
<sql>encrypted</sql>
<default_value>1234pwd</default_value>
<is_null_allowed>false</is_null_allowed>
<validation_pattern/>
<tracking_level>all</tracking_level>
</field>
<field id="password" xsi:type="AttributePassword">
<sql>password</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
<validation_pattern/>
</field>
<field id="onewaypassword" xsi:type="AttributeOneWayPassword">
<sql>onewaypassword</sql>
<default_value/>
<is_null_allowed>false</is_null_allowed>
<validation_pattern/>
</field>
<field id="enum" xsi:type="AttributeEnum">
<sql>enum</sql>
<values>
<value id="yes">yes</value>
<value id="no">no</value>
</values>
<default_value>no</default_value>
<is_null_allowed>false</is_null_allowed>
<display_style>radio_horizontal</display_style>
<dependencies/>
<tracking_level>all</tracking_level>
</field>
<field id="enumset" xsi:type="AttributeEnumSet">
<sql>enumset</sql>
<values>
<value id="low">
<code>low</code>
</value>
<value id="high">
<code>high</code>
</value>
<value id="large">
<code>large</code>
</value>
<value id="tall">
<code>tall</code>
</value>
<value id="thin">
<code>thin</code>
</value>
<value id="long">
<code>long</code>
</value>
<value id="short">
<code>short</code>
</value>
<value id="small">
<code>small</code>
</value>
<value id="big">
<code>big</code>
</value>
</values>
<is_null_allowed>true</is_null_allowed>
<dependencies/>
<tracking_level>all</tracking_level>
</field>
<field id="file" xsi:type="AttributeBlob">
<sql>file</sql>
<is_null_allowed>true</is_null_allowed>
</field>
<field id="html" xsi:type="AttributeHTML">
<sql>html</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
<validation_pattern/>
<width/>
<height>200</height>
<tracking_level>all</tracking_level>
</field>
<field id="image" xsi:type="AttributeImage">
<default_image/>
<is_null_allowed>true</is_null_allowed>
<storage_max_width>128</storage_max_width>
<storage_max_height>128</storage_max_height>
<display_max_width>128</display_max_width>
<display_max_height>128</display_max_height>
<tracking_level>all</tracking_level>
</field>
<field id="integer" xsi:type="AttributeInteger">
<sql>integer</sql>
<default_value>7</default_value>
<is_null_allowed>false</is_null_allowed>
<tracking_level>all</tracking_level>
</field>
<field id="ip_address" xsi:type="AttributeIPAddress">
<sql>ip_address</sql>
<default_value>15.28.255.1</default_value>
<is_null_allowed>false</is_null_allowed>
<validation_pattern/>
<tracking_level>all</tracking_level>
</field>
<field id="percentage" xsi:type="AttributePercentage">
<sql>percentage</sql>
<default_value>50</default_value>
<is_null_allowed>false</is_null_allowed>
<validation_pattern/>
<tracking_level>all</tracking_level>
</field>
<field id="phone" xsi:type="AttributePhoneNumber">
<sql>phone</sql>
<default_value>+33 666333000</default_value>
<is_null_allowed>false</is_null_allowed>
<validation_pattern/>
<tracking_level>all</tracking_level>
</field>
<field id="status" xsi:type="AttributeEnum">
<sql>status</sql>
<values>
<value id="new">new</value>
<value id="investigation">investigation</value>
<value id="cancel">cancel</value>
<value id="done">done</value>
</values>
<default_value>new</default_value>
<is_null_allowed>false</is_null_allowed>
<display_style/>
<dependencies/>
<tracking_level>all</tracking_level>
</field>
<field id="stopwatch" xsi:type="AttributeStopWatch">
<states>
<state id="investigation">investigation</state>
</states>
<working_time/>
<thresholds/>
<always_load_in_tables>true</always_load_in_tables>
<tracking_level>all</tracking_level>
</field>
<field id="stopwatch_started" xsi:type="AttributeSubItem">
<target_attcode>stopwatch</target_attcode>
<item_code>started</item_code>
</field>
<field id="tagset" xsi:type="AttributeTagSet">
<sql>tagset</sql>
<is_null_allowed>true</is_null_allowed>
<max_items/>
<tag_code_max_len/>
<tracking_level>all</tracking_level>
</field>
<field id="text" xsi:type="AttributeText">
<sql>text</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
<validation_pattern/>
<width/>
<height>30</height>
<tracking_level>all</tracking_level>
</field>
<field id="long_text" xsi:type="AttributeLongText">
<sql>long_text</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
<validation_pattern/>
<width/>
<height>50</height>
<tracking_level>all</tracking_level>
</field>
<field id="url" xsi:type="AttributeURL">
<sql>url</sql>
<default_value>http://www.combodo.com</default_value>
<is_null_allowed>false</is_null_allowed>
<validation_pattern/>
<target>_blank</target>
<tracking_level>all</tracking_level>
</field>
<field id="oql" xsi:type="AttributeOQL">
<sql>oql</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
</field>
<field id="boolean" xsi:type="AttributeBoolean">
<sql>boolean</sql>
<default_value/>
<is_null_allowed>true</is_null_allowed>
</field>
</fields>
<presentation/>
<methods/>
</class>
<class id="SubObject" _delta="define">
<parent>TestAbstract</parent>
<properties>
<category>bizmodel,searchable</category>
<abstract>false</abstract>
<db_table>subobject</db_table>
<naming>
<attributes>
<attribute id="testobject_id_friendlyname"/>
<attribute id="name"/>
</attributes>
</naming>
<reconciliation>
<attributes>
<attribute id="name"/>
<attribute id="org_id"/>
<attribute id="testobject_id"/>
</attributes>
</reconciliation>
<uniqueness_rules>
<rule id="unique_name">
<attributes>
<attribute id="name"/>
<attribute id="testobject_id"/>
</attributes>
<filter><![CDATA[]]></filter>
<disabled>false</disabled>
<is_blocking>true</is_blocking>
</rule>
</uniqueness_rules>
</properties>
<fields>
<field id="testobject_id" xsi:type="AttributeExternalKey">
<sql>testobject_id</sql>
<filter/>
<dependencies/>
<is_null_allowed>false</is_null_allowed>
<target_class>TestObject</target_class>
<on_target_delete>DEL_AUTO</on_target_delete>
<tracking_level>all</tracking_level>
<label>Test Object</label>
</field>
<field id="_name" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>name</target_attcode>
</field>
<field id="_meta_enum" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>meta_enum</target_attcode>
</field>
<field id="_org_id" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>org_id</target_attcode>
</field>
<field id="_parent_id" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>parent_id</target_attcode>
</field>
<field id="_caselog" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>caselog</target_attcode>
</field>
<field id="_date" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>date</target_attcode>
</field>
<field id="_date_time" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>date_time</target_attcode>
</field>
<field id="_deadline" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>deadline</target_attcode>
</field>
<field id="_decimal" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>decimal</target_attcode>
</field>
<field id="_duration" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>duration</target_attcode>
</field>
<field id="_email" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>email</target_attcode>
</field>
<field id="_encrypted" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>encrypted</target_attcode>
</field>
<field id="_password" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>password</target_attcode>
</field>
<field id="_onewaypassword" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>onewaypassword</target_attcode>
</field>
<field id="_enum" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>enum</target_attcode>
</field>
<field id="_enumset" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>enumset</target_attcode>
</field>
<field id="_file" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>file</target_attcode>
</field>
<field id="_html" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>html</target_attcode>
</field>
<field id="_image" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>image</target_attcode>
</field>
<field id="_integer" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>integer</target_attcode>
</field>
<field id="_ip_address" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>ip_address</target_attcode>
</field>
<field id="_percentage" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>percentage</target_attcode>
</field>
<field id="_phone" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>phone</target_attcode>
</field>
<field id="_status" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>status</target_attcode>
</field>
<field id="_stopwatch" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>stopwatch</target_attcode>
</field>
<field id="_stopwatch_started" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>stopwatch_started</target_attcode>
</field>
<field id="_tagset" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>tagset</target_attcode>
</field>
<field id="_text" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>text</target_attcode>
</field>
<field id="_long_text" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>long_text</target_attcode>
</field>
<field id="_url" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>url</target_attcode>
</field>
<field id="_oql" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>oql</target_attcode>
</field>
<field id="_boolean" xsi:type="AttributeExternalField">
<extkey_attcode>testobject_id</extkey_attcode>
<target_attcode>boolean</target_attcode>
</field>
</fields>
<presentation/>
<methods/>
</class>
</classes>
</itop_design>

View File

@@ -0,0 +1,197 @@
<?php
namespace Combodo\iTop\Test\UnitTest\Core;
class QueryBuilderExpressionsTest extends \Combodo\iTop\Test\UnitTest\ItopCustomDatamodelTestCase
{
const CREATE_TEST_ORG = true;
/**
* @inheritDoc
*/
public function GetDatamodelDeltaAbsPath(): string
{
return __DIR__."/Delta/all-attributes.xml";
}
public function testICanWriteAndReadAnyTypeOfAttribute()
{
$oTagA = \MetaModel::NewObject(\TagSetFieldData::GetTagDataClassName('TestObject', 'tagset'), [
'code' => 'tagA',
'label' => 'Tag A',
'description' => 'Tag known as "A"'
]);
$oTagA->DBInsert();
$sTargetClass = 'TestObject';
$aValues = [
'name' => [
'value' => 'Tadam!',
'type' => 'php:integer',
],
'org_id' => [
'value' => $this->getTestOrgId(),
'type' => 'php:integer',
],
'parent_id' => [
'value' => 0,
'type' => 'php:integer',
],
'caselog' => [
'value' => '{"items":[{"message":"Hi folks!"}]}',
'type' => 'ormCaseLog',
],
'date' => [
'value' => '2023-10-04',
'type' => 'php:string',
],
'date_time' => [
'value' => '2023-10-04 17:11:54',
'type' => 'php:string',
],
'deadline' => [
'value' => '2023-10-04 17:11:54',
'type' => 'php:string',
],
'decimal' => [
'value' => '123456.78',
'type' => 'php:string',
],
'duration' => [
'value' => 3660, // One hour and one minute
'type' => 'php:integer',
],
'email' => [
'value' => 'john.foo@company.com',
'type' => 'php:string',
],
'encrypted' => [
'value' => 'secret...inDB!',
'type' => 'php:string',
],
'password' => [
'value' => 'abc123',
'type' => 'php:string',
],
'onewaypassword' => [
'value' => 'az"e(t-yè',
'type' => 'php:string',
],
'enum' => [
'value' => 'yes',
'type' => 'php:string',
],
'enumset' => [
'value' => 'low|high',
'type' => 'php:string',
],
'file' => [
'value' => '{"data":"blahblah","mimetype":"text/plain","filename":"trash.txt", "downloads_count":0}',
'type' => 'ormDocument',
],
'html' => [
'value' => '<p><b>Hello</b>&nbsp;world!</p>',
'type' => 'php:string',
],
'image' => [
'value' => '{"data":"notanimage-sowhat?","mimetype":"image/png","filename":"trash.png", "downloads_count":0}',
'type' => 'ormDocument',
],
'integer' => [
'value' => 123,
'type' => 'php:integer',
],
'ip_address' => [
'value' => '192.158.1.38',
'type' => 'php:string',
],
'percentage' => [
'value' => 49.3,
'type' => 'php:double',
],
'phone' => [
'value' => '+33476123456',
'type' => 'php:string',
],
'status' => [
'value' => 'investigation',
'type' => 'php:string',
],
'stopwatch' => [
'value' => null,
'type' => 'ormStopWatch',
],
'tagset' => [
'value' => 'tagA',
'type' => 'php:string',
],
'text' => [
'value' => 'Hello world!',
'type' => 'php:string',
],
'long_text' => [
'value' => 'Hello world!',
'type' => 'php:string',
],
'url' => [
'value' => 'http://www.combodo.com/void',
'type' => 'php:string',
],
'oql' => [
'value' => 'SELECT Organization',
'type' => 'php:string',
],
'boolean' => [
'value' => true,
'type' => 'php:boolean',
],
];
$aValuesToSet = [];
foreach ($aValues as $sAttCode => $aValueData) {
if (substr($aValueData['type'], 0, 4) == 'php:') {
$aValuesToSet[$sAttCode] = $aValueData['value'];
} else {
$oAttDef = \MetaModel::GetAttributeDef($sTargetClass, $sAttCode);
$oJSONObject = is_null($aValueData['value']) ? null : json_decode($aValueData['value'], false);
$aValuesToSet[$sAttCode] = $oAttDef->FromJSONToValue($oJSONObject);
}
}
// Test that I can write without any error (such as malformed SQL query, that would throw an exception)
$oObject = \MetaModel::NewObject($sTargetClass, $aValuesToSet);
$oObject->DBInsert();
// Test that I can read without any error (such as malformed SQL query, that would throw an exception)
$iTestObject = $oObject->GetKey();
$oObjectFromDB = \MetaModel::GetObject($sTargetClass, $iTestObject);
// Test that each value matches the original value
foreach ($aValues as $sAttCode => $aValueData) {
$oAttDef = \MetaModel::GetAttributeDef($sTargetClass, $sAttCode);
static::assertTrue($oAttDef->Equals(
$oObject->Get($sAttCode),
$oObjectFromDB->Get($sAttCode)
), "Value of attribute '$sAttCode' has been altered after DB write + read");
}
// Create an indirection
$oSubObject = \MetaModel::NewObject('SubObject', [
'name' => 'subobject for '.$iTestObject,
'testobject_id' => $iTestObject
]);
$oSubObject->DBInsert();
// Test that it can be read from the DB
$iSubObject = $oSubObject->GetKey();
$oSubObjectFromDB = \MetaModel::GetObject('SubObject', $iSubObject);
// Test that each external field value matches the original value
foreach ($aValues as $sAttCode => $aValueData) {
$sExtFieldAttCode = '_'.$sAttCode;
$oAttDef = \MetaModel::GetAttributeDef($sTargetClass, $sAttCode);
static::assertTrue($oAttDef->Equals($oObject->Get($sAttCode), $oSubObjectFromDB->Get($sExtFieldAttCode)), "Value of attribute '$sAttCode' not correctly read as an external key");
}
}
}