Navigation Menu

Skip to content
This repository has been archived by the owner on Dec 27, 2023. It is now read-only.

Commit

Permalink
fix(TB Model CustomFieldFilter) - introduce all "record" features (no…
Browse files Browse the repository at this point in the history
…tDefinedBy etc.)

Change-Id: Ia39a5eb75000c5c830bfed8cad19e2d035de6595
Reviewed-on: http://gerrit.tine20.com/customers/16505
Tested-by: Jenkins CI (http://ci.tine20.com/) <tine20-jenkins@metaways.de>
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
  • Loading branch information
paulmhh committed Apr 30, 2020
1 parent 5f3be1f commit 3bc3a7a
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 48 deletions.
130 changes: 100 additions & 30 deletions tests/tine20/Sales/CustomFieldTest.php
Expand Up @@ -17,7 +17,7 @@
/**
* Test class for Tinebase_CustomField
*/
class Sales_CustomFieldTest extends PHPUnit_Framework_TestCase
class Sales_CustomFieldTest extends TestCase // PHPUnit_Framework_TestCase
{
/**
* unit under test (UIT)
Expand All @@ -27,22 +27,11 @@ class Sales_CustomFieldTest extends PHPUnit_Framework_TestCase

/**
* transaction id if test is wrapped in an transaction
*/
protected $_transactionId = NULL;
*
protected $_transactionId = NULL;*/

protected $_user = NULL;

/**
* Runs the test methods of this class.
*
* @access public
* @static
*/
public static function main()
{
$suite = new PHPUnit_Framework_TestSuite('Sales_CustomFieldTest');
PHPUnit_TextUI_TestRunner::run($suite);
}


/**
* Sets up the fixture.
Expand All @@ -52,7 +41,9 @@ public static function main()
*/
protected function setUp()
{
$this->_transactionId = Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
parent::setUp();

//$this->_transactionId = Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
$this->_instance = Tinebase_CustomField::getInstance();
}

Expand All @@ -64,13 +55,11 @@ protected function setUp()
*/
protected function tearDown()
{
if ($this->_transactionId) {
Tinebase_TransactionManager::getInstance()->rollBack();
}

if ($this->_user) {
Tinebase_Core::set(Tinebase_Core::USER, $this->_user);
}

parent::tearDown();
}

/**
Expand All @@ -97,12 +86,8 @@ public static function getCustomField($config = array())
)
), $config));
}

/**
* test searching records by record as a customfield type
* https://forge.tine20.org/mantisbt/view.php?id=6730
*/
public function testSearchByRecord()

protected function createCustomFieldTestData()
{
$cf = self::getCustomField(array(
'application_id' => Tinebase_Application::getInstance()->getApplicationByName('Addressbook')->getId(),
Expand All @@ -127,12 +112,97 @@ public function testSearchByRecord()
// contact1 with customfield record = contract
$contact1 = new Addressbook_Model_Contact(array('n_given' => 'Rita', 'n_family' => 'Blütenrein'));
$contact1->customfields = array($cf->name => $contract->getId());
Addressbook_Controller_Contact::getInstance()->create($contact1, false);
$contact1 = Addressbook_Controller_Contact::getInstance()->create($contact1, false);

// contact2 with customfield record is not set -> should act like without this record
$contact2 = new Addressbook_Model_Contact(array('n_given' => 'Rainer', 'n_family' => 'Blütenrein'));
$contact2 = Addressbook_Controller_Contact::getInstance()->create($contact2, false);

return [$cf, $contract, $contact1, $contact2];
}

public function testSearchByRecordNotDefinedBy()
{
list($cf, $contract, $contact1, $contact2) = $this->createCustomFieldTestData();

$result = (new Addressbook_Frontend_Json())->searchContacts([[
"condition" => "AND", "filters" => [
["field" => "customfield", "operator" => 'notDefinedBy:AND',
"value" => ["cfId" => $cf->getId(), "value" => [
['field' => ':id', 'operator' => 'equals', 'value' => $contract->getId()]
]]],
['field' => 'n_family', 'operator' => 'equals', 'value' => 'Blütenrein']
]
]], []);

static::assertCount(1, $result['results']);
static::assertSame($contact2->getId(), $result['results'][0]['id']);
}

public function testSearchByRecordNotNull()
{
list($cf, $contract, $contact1, $contact2) = $this->createCustomFieldTestData();

$result = (new Addressbook_Frontend_Json())->searchContacts([[
"condition" => "OR",
"filters" => array(
array(
"condition" => "AND",
"filters" => array(
array(
"field" => "customfield",
"operator" => 'notDefinedBy:AND',
"value" => array("cfId" => $cf->getId(), "value" => [
['field' => ':id', 'operator' => 'in', 'value' => null]
])
),
)
)
)
]
], []);

static::assertCount(1, $result['results']);
static::assertSame($contact1->getId(), $result['results'][0]['id']);
}

public function testSearchByRecordNull()
{
list($cf, $contract, $contact1, $contact2) = $this->createCustomFieldTestData();

$result = (new Addressbook_Frontend_Json())->searchContacts([[
"condition" => "OR",
"filters" => array(
array(
"condition" => "AND",
"filters" => array(
array(
"field" => "customfield",
"operator" => "AND",
"value" => array("cfId" => $cf->getId(), "value" => [
['field' => ':id', 'operator' => 'in', 'value' => null]
])
),
)
)
)
]
], []);

static::assertGreaterThan(1, count($result['results']));
foreach ($result['results'] as $res) {
static::assertNotSame($contact1->getId(), $res['id']);
}
}

/**
* test searching records by record as a customfield type
* https://forge.tine20.org/mantisbt/view.php?id=6730
*/
public function testSearchByRecord()
{
list($cf, $contract, $contact1, $contact2) = $this->createCustomFieldTestData();

$json = new Addressbook_Frontend_Json();

$result = $json->searchContacts(array(
Expand Down Expand Up @@ -194,8 +264,8 @@ public function testSearchByRecord()
$contact2->customfields = array($cf->name => $contract2->getId());
Addressbook_Controller_Contact::getInstance()->update($contact2, false);

Tinebase_TransactionManager::getInstance()->commitTransaction($this->_transactionId);
$this->_transactionId = null;
//Tinebase_TransactionManager::getInstance()->commitTransaction($this->_transactionId);
//$this->_transactionId = null;

$result = $json->searchContacts(array(
array(
Expand Down Expand Up @@ -232,4 +302,4 @@ public function testSearchByRecord()
$this->assertEquals('Blütenrein', $result['results'][1]['n_family'],
'Rainer and Rita should have been found.');
}
}
}
51 changes: 34 additions & 17 deletions tine20/Tinebase/Model/Filter/CustomField.php
Expand Up @@ -158,7 +158,7 @@ public function __construct($_fieldOrData, $_operator = NULL, $_value = NULL, ar
$this->_subFilterController = Tinebase_Core::getApplicationInstance($modelName);
$this->_subFilter = Tinebase_Model_Filter_FilterGroup::getFilterForModel($modelName);
$filterClass = null;
$this->_operators = array('AND', 'OR');
$this->_operators = ['AND', 'OR', 'notDefinedBy:AND', 'notDefinedBy:OR'];
} else {
$filterClass = Tinebase_Model_Filter_Id::class;
}
Expand All @@ -168,6 +168,7 @@ public function __construct($_fieldOrData, $_operator = NULL, $_value = NULL, ar
throw new Tinebase_Exception_NotImplemented('filter for records type not implemented yet');
break;
default:
$this->_operators = ['contains', 'AND', 'OR'];
// nothing here - parent is used
}

Expand All @@ -180,9 +181,6 @@ public function __construct($_fieldOrData, $_operator = NULL, $_value = NULL, ar
'options' => $this->_valueFilterOptions
]);
$this->_operators = $this->_valueFilter->getOperators();
} else {
// allow default operators
$this->_operators = ['contains', 'AND', 'OR'];
}

parent::__construct($_fieldOrData, $_operator, $_value, $_options);
Expand Down Expand Up @@ -224,23 +222,42 @@ public function appendFilterSql($_select, $_backend)

if (null !== $this->_subFilterController && null !== $this->_subFilter) {
$value = $this->_value['value'];
array_walk($value, function(&$val) {
if (isset($val['field']) && strpos($val['field'], ':') === 0) {
$val['field'] = substr($val['field'], 1);
}
});
$this->_subFilter->setFromArray($value);
$ids = $this->_subFilterController->search($this->_subFilter, null, false, true);
if (count($ids)) {
$this->_valueFilter = new Tinebase_Model_Filter_Id(

$queryForEmpty = count($value) === 1 && isset($value[0]) &&
is_array($value[0]) && array_key_exists('value', $value[0]) && empty($value[0]['value']);
$notOperator = strpos($this->_operator, 'not') === 0;

if ($queryForEmpty) {
(new Tinebase_Model_Filter_Id(
[
'field' => 'value',
'operator' => 'in',
'value' => $ids,
'operator' => $notOperator ? 'notnull' : 'isnull',
'value' => true,
'options' => $this->_valueFilterOptions
]);
]))->appendFilterSql($_select, $_backend);
} else {
$_select->where('1=2');
array_walk($value, function (&$val) {
if (isset($val['field']) && strpos($val['field'], ':') === 0) {
$val['field'] = substr($val['field'], 1);
}
});
$this->_subFilter->setFromArray($value);
$ids = $this->_subFilterController->search($this->_subFilter, null, false, true);
if (count($ids)) {
$this->_valueFilter = new Tinebase_Model_Filter_Id(
[
'field' => 'value',
'operator' => $notOperator ? 'notin' : 'in',
'value' => $ids,
'options' => $this->_valueFilterOptions
]);
} else {
if ($notOperator) {
$_select->where('1=1');
} else {
$_select->where('1=2');
}
}
}
}
if (null !== $this->_valueFilter) {
Expand Down
4 changes: 3 additions & 1 deletion tine20/Tinebase/Model/Filter/Id.php
Expand Up @@ -5,7 +5,7 @@
* @package Tinebase
* @subpackage Filter
* @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
* @copyright Copyright (c) 2007-2013 Metaways Infosystems GmbH (http://www.metaways.de)
* @copyright Copyright (c) 2007-2020 Metaways Infosystems GmbH (http://www.metaways.de)
* @author Philipp Schüle <p.schuele@metaways.de>
*/

Expand All @@ -28,6 +28,7 @@ class Tinebase_Model_Filter_Id extends Tinebase_Model_Filter_Abstract
'in',
'notin',
'isnull',
'notnull',
);

/**
Expand All @@ -39,6 +40,7 @@ class Tinebase_Model_Filter_Id extends Tinebase_Model_Filter_Abstract
'in' => array('sqlop' => ' IN (?)'),
'notin' => array('sqlop' => ' NOT IN (?)'),
'isnull' => array('sqlop' => ' IS NULL'),
'notnull' => array('sqlop' => ' IS NOT NULL'),
);

/**
Expand Down

0 comments on commit 3bc3a7a

Please sign in to comment.