/** * Returns all relatable models for this app * * @return array */ public function getRelatableModels() { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' This method is deprecated and will be removed. Please use Tinebase_ModelFactory with Tinebase_ModelConfiguration!'); } if (property_exists($this, '_relatableModels') && is_array($this->_relatableModels)) { return Tinebase_Relations::getConstraintsConfigs($this->_relatableModels); } else { return array(); } }
/** * handles relations on update multiple * * @param string $key * @param string $value * @throws Tinebase_Exception_Record_DefinitionFailure */ protected function _handleRelationsOnUpdateMultiple($key, $value) { $getRelations = true; preg_match('/%(.+)-((.+)_Model_(.+))/', $key, $a); if (count($a) < 4) { throw new Tinebase_Exception_Record_DefinitionFailure('The relation to delete/set is not configured properly!'); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Handle relations for ' . $this->_modelName); } $relConfig = Tinebase_Relations::getConstraintsConfigs(array($this->_modelName, $a[2])); $constraintsConfig = NULL; if ($relConfig) { foreach ($relConfig as $config) { if ($config['relatedApp'] == $a[3] && $config['relatedModel'] == $a[4] && isset($config['config']) && is_array($config['config'])) { foreach ($config['config'] as $constraint) { if ($constraint['type'] == $a[1]) { $constraintsConfig = $constraint; break 2; } } } } } // update multiple is not possible without having a constraints config if (!$constraintsConfig) { throw new Tinebase_Exception_Record_DefinitionFailure('No relation definition could be found for this model!'); } $rel = array('own_model' => $this->_modelName, 'own_backend' => 'Sql', 'own_degree' => isset($constraintsConfig['sibling']) ? $constraintsConfig['sibling'] : 'sibling', 'related_model' => $a[2], 'related_backend' => 'Sql', 'type' => isset($constraintsConfig['type']) ? $constraintsConfig['type'] : ' ', 'remark' => isset($constraintsConfig['defaultRemark']) ? $constraintsConfig['defaultRemark'] : ' '); if (!$this->_removeRelations) { $this->_removeRelations = array($rel); } else { $this->_removeRelations[] = $rel; } if (!empty($value)) { // delete relations in iterator $rel['related_id'] = $value; if (!$this->_newRelations) { $this->_newRelations = array($rel); } else { $this->_newRelations[] = $rel; } } if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' New relations: ' . print_r($this->_newRelations, true) . ' Remove relations: ' . print_r($this->_removeRelations, true)); } }
/** * tests if constraints config is called properly * * @see #8840: relations config - constraints from the other side * - validate in backend * * https://forge.tine20.org/mantisbt/view.php?id=8840 */ public function testGetConstraintsConfigs() { $result = Tinebase_Relations::getConstraintsConfigs('Sales_Model_Contract'); $this->assertEquals(12, count($result)); foreach ($result as $item) { if ($item['ownRecordClassName'] == 'Sales_Model_Contract' && $item['relatedRecordClassName'] == 'Timetracker_Model_Timeaccount') { $this->assertEquals('Contract', $item['ownModel']); $this->assertEquals('Timeaccount', $item['relatedModel']); $this->assertEquals('', $item['defaultType']); $this->assertEquals('TIME_ACCOUNT', $item['config'][0]['type']); $this->assertSame(0, $item['config'][0]['max']); } elseif ($item['ownRecordClassName'] == 'Timetracker_Model_Timeaccount' && $item['relatedRecordClassName'] == 'Sales_Model_Contract') { $this->assertEquals('Contract', $item['relatedModel']); $this->assertEquals('Timeaccount', $item['ownModel']); $this->assertEquals('TIME_ACCOUNT', $item['config'][0]['type']); $this->assertEquals(TRUE, $item['reverted']); $this->assertSame(1, $item['config'][0]['max']); } } }
/** * handles relations on update multiple * * Syntax 1 (old): key: '%<type>-<related_model>', value: <related_id> * Syntax 2 : key: '%<add|remove|replace>', value: <relation json> * * @param string $key * @param string $value * @throws Tinebase_Exception_Record_DefinitionFailure */ protected function _handleRelationsOnUpdateMultiple($key, $value) { if (preg_match('/%(add|remove|replace)/', $key, $matches)) { $action = $matches[1]; $rel = json_decode($value, true); } else { if (preg_match('/%(.+)-((.+)_Model_(.+))/', $key, $a)) { $action = $value ? 'replace' : 'remove'; $rel = array('related_model' => $a[2], 'type' => $a[1], 'related_id' => $value); } else { throw new Tinebase_Exception_Record_DefinitionFailure('The relation to delete/set is not configured properly!'); } } // find constraint config $constraintsConfig = array(); $relConfig = Tinebase_Relations::getConstraintsConfigs(array($this->_modelName, $rel['related_model'])); if ($relConfig) { foreach ($relConfig as $config) { if ($rel['related_model'] == "{$config['relatedApp']}_Model_{$config['relatedModel']}" && isset($config['config']) && is_array($config['config'])) { foreach ($config['config'] as $constraint) { if (isset($rel['type']) && isset($constraint['type']) && $constraint['type'] == $rel['type']) { $constraintsConfig = $constraint; break 2; } } } } } // apply defaults $rel = array_merge($rel, array('own_model' => $this->_modelName, 'own_backend' => 'Sql', 'related_backend' => 'Sql', 'related_degree' => isset($rel['related_degree']) ? $rel['related_degree'] : (isset($constraintsConfig['sibling']) ? isset($constraintsConfig['sibling']) : 'sibling'), 'type' => isset($rel['type']) ? $rel['type'] : (isset($constraintsConfig['type']) ? isset($constraintsConfig['type']) : ' '), 'remark' => isset($rel['remark']) ? $rel['remark'] : (isset($constraintsConfig['defaultRemark']) ? isset($constraintsConfig['defaultRemark']) : ' '))); if (in_array($action, array('remove', 'replace'))) { $this->_removeRelations ?: array(); $this->_removeRelations[] = $rel; } if (in_array($action, array('add', 'replace'))) { $this->_newRelations ?: array(); $this->_newRelations[] = $rel; } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' New relations: ' . print_r($this->_newRelations, true) . ' Remove relations: ' . print_r($this->_removeRelations, true)); } }