/** * Sets up the fixture. * This method is called before a test is executed. * * @access protected */ protected function setUp() { $this->_transactionId = Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb()); $this->_instance = Tinebase_CustomField::getInstance(); Sales_Controller_Contract::getInstance()->setNumberPrefix(); Sales_Controller_Contract::getInstance()->setNumberZerofill(); }
/** * the constructor * * don't use the constructor. use the singleton */ private function __construct() { $this->_applicationName = 'Admin'; $this->_modelName = 'Tinebase_Model_CustomField_Config'; $this->_doContainerACLChecks = FALSE; $this->_backend = new Tinebase_CustomField_Config(); $this->_customfieldController = Tinebase_CustomField::getInstance(); }
/** * update from 0.5 to 2.0 * - copy entries from timetracker_timesheet_custom to customfield table * - drop timetracker_timesheet_custom table */ public function update_5() { // get all timetracker/timesheet custom fields $customfields = Tinebase_CustomField::getInstance()->getCustomFieldsForApplication(Tinebase_Application::getInstance()->getApplicationByName('Timetracker'), 'Timetracker_Model_Timesheet'); if (count($customfields) > 0) { $customfields->addIndices(array('name')); // get all custom field values $select = $this->_db->select()->from(SQL_TABLE_PREFIX . 'timetracker_timesheet_custom')->order('name ASC'); $stmt = $this->_db->query($select); $queryResult = $stmt->fetchAll(); //if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . print_r($queryResult, TRUE)); // insert values into customfield table $cfValueBackend = new Tinebase_Backend_Sql(array('modelName' => 'Tinebase_Model_CustomField_Value', 'tableName' => 'customfield')); foreach ($queryResult as $row) { if (!isset($customfield) || $customfield->name != $row['name']) { $customfield = $customfields->filter('name', $row['name'])->getFirstRecord(); } $cfValue = new Tinebase_Model_CustomField_Value(array('record_id' => $row['record_id'], 'customfield_id' => $customfield->getId(), 'value' => $row['value'])); $cfValueBackend->create($cfValue); } } // drop obsolete table $this->dropTable('timetracker_timesheet_custom'); $this->setApplicationVersion('Timetracker', '2.0'); }
/** * get lead * * @param boolean $addCf * @param boolean $addTags * @return Crm_Model_Lead */ protected function _getLead($addCf = TRUE, $addTags = TRUE) { if ($addCf) { $cfc = Tinebase_CustomFieldTest::getCustomField(array('application_id' => Tinebase_Application::getInstance()->getApplicationByName('Crm')->getId(), 'model' => 'Crm_Model_Lead', 'name' => Tinebase_Record_Abstract::generateUID())); $this->_cfcName = $cfc->name; $cfs = array($this->_cfcName => '1234'); Tinebase_CustomField::getInstance()->addCustomField($cfc); } else { $cfs = array(); } if ($addTags) { $tags = array(array('name' => 'lead tag', 'type' => Tinebase_Model_Tag::TYPE_SHARED)); } else { $tags = array(); } return new Crm_Model_Lead(array('lead_name' => 'PHPUnit', 'leadstate_id' => 1, 'leadtype_id' => 1, 'leadsource_id' => 1, 'container_id' => Tinebase_Container::getInstance()->getDefaultContainer('Crm')->getId(), 'start' => Tinebase_DateTime::now(), 'description' => 'Description', 'end' => NULL, 'turnover' => 0, 'probability' => 70, 'end_scheduled' => NULL, 'tags' => $tags, 'customfields' => $cfs)); }
/** * get and create timesheet custom fields * * @todo add more values (options, order, ...) */ public function importTimesheetCustomFields() { // get all custom fields $select = $this->_db->select()->from($this->_oldTablePrefix . 'timesheet_extra', 'ts_extra_name')->distinct()->group('ts_extra_name'); $stmt = $this->_db->query($select); $queryResult = $stmt->fetchAll(); foreach ($queryResult as $row) { $customField = new Tinebase_Model_CustomField_Config(array('application_id' => Tinebase_Application::getInstance()->getApplicationByName('Timetracker')->getId(), 'name' => $row['ts_extra_name'], 'label' => $row['ts_extra_name'], 'model' => 'Timetracker_Model_Timesheet', 'type' => 'textfield', 'length' => 256)); try { Tinebase_CustomField::getInstance()->addCustomField($customField); } catch (Zend_Db_Statement_Exception $ze) { // ignore duplicates if (!preg_match("/SQLSTATE\\[23000\\]/", $ze->getMessage())) { throw $ze; } } } }
/** * created customfield config * * @return Tinebase_Model_CustomField_Config */ protected function _createCustomfield($cfName = NULL) { $cfName = $cfName !== NULL ? $cfName : Tinebase_Record_Abstract::generateUID(); $cfc = Tinebase_CustomFieldTest::getCustomField(array('application_id' => Tinebase_Application::getInstance()->getApplicationByName('Addressbook')->getId(), 'model' => 'Addressbook_Model_Contact', 'name' => $cfName)); $createdCustomField = Tinebase_CustomField::getInstance()->addCustomField($cfc); $this->_customfieldIdsToDelete[] = $createdCustomField->getId(); return $createdCustomField; }
/** * appends sql to given select statement * * @param Zend_Db_Select $_select * @param Tinebase_Backend_Sql_Abstract $_backend * @throws Tinebase_Exception_UnexpectedValue */ public function appendFilterSql($_select, $_backend) { // don't take empty filter into account if (empty($this->_value) || !is_array($this->_value) || !isset($this->_value['cfId']) || empty($this->_value['cfId']) || !isset($this->_value['value'])) { return; } else { if ($this->_operator == 'in') { throw new Tinebase_Exception_UnexpectedValue('Operator "in" not supported.'); } } // make sure $correlationName is a string $correlationName = Tinebase_Record_Abstract::generateUID(30); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Adding custom field filter: ' . print_r($this->_value, true)); } $db = Tinebase_Core::getDb(); $idProperty = $db->quoteIdentifier($this->_options['idProperty']); // per left join we add a customfield column named as the customfield and filter this joined column // NOTE: we name the column we join like the customfield, to be able to join multiple customfield criteria (multiple invocations of this function) $what = array($correlationName => SQL_TABLE_PREFIX . 'customfield'); $on = $db->quoteIdentifier("{$correlationName}.record_id") . " = {$idProperty} AND " . $db->quoteIdentifier("{$correlationName}.customfield_id") . " = " . $db->quote($this->_value['cfId']); $_select->joinLeft($what, $on, array()); $valueIdentifier = $db->quoteIdentifier("{$correlationName}.value"); switch ($this->_cfRecord->definition['type']) { case 'date': case 'datetime': $customfields = Tinebase_CustomField::getInstance()->search($this->_subFilter); if ($customfields->count()) { $where = $db->quoteInto($idProperty . ' IN (?) ', $customfields->record_id); } else { $where = '1=2'; } break; default: if (!$this->_value['value']) { $where = $db->quoteInto($valueIdentifier . ' IS NULL OR ' . $valueIdentifier . ' = ?', $this->_value['value']); } else { $value = $this->_replaceWildcards($this->_value['value']); if (($this->_cfRecord->definition['type'] == 'keyField' || $this->_cfRecord->definition['type'] == 'record') && $this->_operator == 'not') { $where = $db->quoteInto($valueIdentifier . ' IS NULL OR ' . $valueIdentifier . $this->_opSqlMap[$this->_operator]['sqlop'], $value); } else { $where = $db->quoteInto($valueIdentifier . $this->_opSqlMap[$this->_operator]['sqlop'], $value); } } } $_select->where($where); }
/** * Updates multiple entries * * @param array $_ids to update * @param array $_data * @return integer number of affected rows * @throws Tinebase_Exception_Record_Validation|Tinebase_Exception_InvalidArgument */ public function updateMultiple($_ids, $_data) { if (empty($_ids)) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' No records updated.'); } return 0; } // separate CustomFields $myFields = array(); $customFields = array(); foreach ($_data as $key => $value) { if (stristr($key, '#')) { $customFields[substr($key, 1)] = $value; } else { $myFields[$key] = $value; } } // handle CustomFields if (count($customFields)) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' CustomFields found.'); } Tinebase_CustomField::getInstance()->saveMultipleCustomFields($this->_modelName, $_ids, $customFields); } // handle StdFields if (!count($myFields)) { return 0; } $identifier = $this->_getRecordIdentifier(); $recordArray = $myFields; $recordArray = array_intersect_key($recordArray, $this->getSchema()); $this->_prepareData($recordArray); $where = array($this->_db->quoteInto($this->_db->quoteIdentifier($identifier) . ' IN (?)', $_ids)); //if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . print_r($where, TRUE)); return $this->_db->update($this->_tablePrefix . $this->_tableName, $recordArray, $where); }
/** * get duplicate filter * * @param Tinebase_Record_Interface $_record * @return Tinebase_Model_Filter_FilterGroup|NULL */ protected function _getDuplicateFilter(Tinebase_Record_Interface $_record) { if (empty($this->_duplicateCheckFields)) { return NULL; } if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Duplicate check fields: ' . print_r($this->_duplicateCheckFields, TRUE)); } $filters = array(); foreach ($this->_duplicateCheckFields as $group) { $addFilter = array(); if (!is_array($group)) { $group = array($group); } foreach ($group as $field) { if (!empty($_record->{$field})) { if ($field === 'relations') { $relationFilter = $this->_getRelationDuplicateFilter($_record); if ($relationFilter) { $addFilter[] = $relationFilter; } } else { $addFilter[] = array('field' => $field, 'operator' => 'equals', 'value' => $_record->{$field}); } } else { if (isset($_record->customfields[$field])) { $customFieldConfig = Tinebase_CustomField::getInstance()->getCustomFieldByNameAndApplication($this->_applicationName, $field, $this->_modelName); if ($customFieldConfig) { $addFilter[] = array('field' => 'customfield', 'operator' => 'equals', 'value' => array('value' => $_record->customfields[$field], 'cfId' => $customFieldConfig->getId())); } } } } if (!empty($addFilter)) { $filters[] = array('condition' => 'AND', 'filters' => $addFilter); } } if (empty($filters)) { return NULL; } $filterClass = $this->_modelName . 'Filter'; $filterData = count($filters) > 1 ? array(array('condition' => 'OR', 'filters' => $filters)) : $filters; // exclude own record if it has an id $recordId = $_record->getId(); if (!empty($recordId)) { $filterData[] = array('field' => 'id', 'operator' => 'notin', 'value' => array($recordId)); } $filter = new $filterClass($filterData); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($filter->toArray(), TRUE)); } return $filter; }
/** * try to add a Timesheet with custom fields (check grants) */ public function testAddTimesheetWithCustomFieldGrants() { $value = 'test'; $cf = $this->_getCustomField(); $timesheetArray = $this->_getTimesheet()->toArray(); $timesheetArray[$cf->name] = $value; $ts = $this->_json->saveTimesheet($timesheetArray); // test with default grants $this->assertTrue(array_key_exists($cf->name, $ts['customfields']), 'customfield should be readable'); $this->assertEquals($value, $ts['customfields'][$cf->name]); // remove all grants Tinebase_CustomField::getInstance()->setGrants($cf, array()); $ts = $this->_json->getTimesheet($ts['id']); $this->assertTrue(!array_key_exists('customfields', $ts), 'customfields should not be readable'); $ts = $this->_updateCfOfTs($ts, $cf->name, 'try to update'); // only read allowed Tinebase_CustomField::getInstance()->setGrants($cf, array(Tinebase_Model_CustomField_Grant::GRANT_READ)); $ts = $this->_json->getTimesheet($ts['id']); $this->assertTrue(array_key_exists($cf->name, $ts['customfields']), 'customfield should be readable again'); $this->assertEquals($value, $ts['customfields'][$cf->name], 'value should not have changed'); $ts = $this->_updateCfOfTs($ts, $cf->name, 'try to update'); $this->assertEquals($value, $ts['customfields'][$cf->name], 'value should still not have changed'); }
/** * resolve multiple record fields (Tinebase_ModelConfiguration._recordsFields) * * @param Tinebase_Record_RecordSet $_records * @param Tinebase_ModelConfiguration $modelConfiguration * @param boolean $multiple * @throws Tinebase_Exception_UnexpectedValue */ protected function _resolveMultipleRecordFields(Tinebase_Record_RecordSet $_records, $modelConfiguration = NULL, $multiple = false) { if (!$modelConfiguration || !$_records->count()) { return; } if (!($resolveFields = $modelConfiguration->recordsFields)) { return; } $ownIds = $_records->{$modelConfiguration->idProperty}; // iterate fields to resolve foreach ($resolveFields as $fieldKey => $c) { $config = $c['config']; // resolve records, if omitOnSearch is definitively set to FALSE (by default they won't be resolved on search) if ($multiple && !(isset($config['omitOnSearch']) && $config['omitOnSearch'] === FALSE)) { continue; } if (!isset($config['controllerClassName'])) { throw new Tinebase_Exception_UnexpectedValue('Controller class name needed'); } // fetch the fields by the refIfField /** @var Tinebase_Controller_Record_Interface|Tinebase_Controller_SearchInterface $controller */ /** @noinspection PhpUndefinedMethodInspection */ $controller = $config['controllerClassName']::getInstance(); $filterName = $config['filterClassName']; $filterArray = array(); // addFilters can be added and must be added if the same model resides in more than one records fields if (isset($config['addFilters']) && is_array($config['addFilters'])) { $filterArray = $config['addFilters']; } /** @var Tinebase_Model_Filter_FilterGroup $filter */ $filter = new $filterName($filterArray); $filter->addFilter(new Tinebase_Model_Filter_Id(array('field' => $config['refIdField'], 'operator' => 'in', 'value' => $ownIds))); $paging = NULL; if (isset($config['paging']) && is_array($config['paging'])) { $paging = new Tinebase_Model_Pagination($config['paging']); } $foreignRecords = $controller->search($filter, $paging); /** @var Tinebase_Record_Interface $foreignRecordClass */ $foreignRecordClass = $foreignRecords->getRecordClassName(); $foreignRecordModelConfiguration = $foreignRecordClass::getConfiguration(); $foreignRecords->setTimezone(Tinebase_Core::getUserTimezone()); $foreignRecords->convertDates = true; $fr = $foreignRecords->getFirstRecord(); // @todo: resolve alarms? // @todo: use parts parameter? if ($foreignRecordModelConfiguration->resolveRelated && $fr) { if ($fr->has('notes')) { Tinebase_Notes::getInstance()->getMultipleNotesOfRecords($foreignRecords); } if ($fr->has('tags')) { Tinebase_Tags::getInstance()->getMultipleTagsOfRecords($foreignRecords); } if ($fr->has('relations')) { $relations = Tinebase_Relations::getInstance()->getMultipleRelations($foreignRecordClass, 'Sql', $foreignRecords->{$fr->getIdProperty()}); $foreignRecords->setByIndices('relations', $relations); } if ($fr->has('customfields')) { Tinebase_CustomField::getInstance()->resolveMultipleCustomfields($foreignRecords); } if ($fr->has('attachments') && Tinebase_Core::isFilesystemAvailable()) { Tinebase_FileSystem_RecordAttachments::getInstance()->getMultipleAttachmentsOfRecords($foreignRecords); } } if ($foreignRecords->count() > 0) { /** @var Tinebase_Record_Interface $record */ foreach ($_records as $record) { $filtered = $foreignRecords->filter($config['refIdField'], $record->getId())->toArray(); $filtered = $this->_resolveAfterToArray($filtered, $foreignRecordModelConfiguration, TRUE); $record->{$fieldKey} = $filtered; } } else { $_records->{$fieldKey} = NULL; } } }
/** * Sets up the fixture. * This method is called before a test is executed. * * @access protected */ protected function setUp() { $this->_instance = Tinebase_CustomField::getInstance(); }
/** * get custom field names for this app * * @return array */ protected function _getCustomFieldNames() { if ($this->_customFieldNames === NULL) { $this->_customFieldNames = Tinebase_CustomField::getInstance()->getCustomFieldsForApplication($this->_applicationName, $this->_modelName)->name; } return $this->_customFieldNames; }
/** * update custom field * * @param Tinebase_Model_CustomField_Config $_customField * @return Tinebase_Model_CustomField_Config */ public function updateCustomField(Tinebase_Model_CustomField_Config $_record) { $this->_clearCache(); $result = $this->_backendConfig->update($_record); Tinebase_CustomField::getInstance()->setGrants($result, Tinebase_Model_CustomField_Grant::getAllGrants()); return $result; }
/** * created customfield config * * @return Tinebase_Model_CustomField_Config */ protected function _createCustomfield() { $cfName = Tinebase_Record_Abstract::generateUID(); $cfc = new Tinebase_Model_CustomField_Config(array('application_id' => Tinebase_Application::getInstance()->getApplicationByName('Addressbook')->getId(), 'name' => $cfName, 'model' => 'Addressbook_Model_Contact', 'definition' => array('label' => Tinebase_Record_Abstract::generateUID(), 'type' => 'string', 'uiconfig' => array('xtype' => Tinebase_Record_Abstract::generateUID(), 'length' => 10, 'group' => 'unittest', 'order' => 100)))); $createdCustomField = Tinebase_CustomField::getInstance()->addCustomField($cfc); $this->_customfieldIdsToDelete[] = $createdCustomField->getId(); return $createdCustomField; }
/** * create customfield value (tr_budget) for timeaccounts starting with S-AB and moves the value from budget to tr_budget */ public function moveBudget() { $filter = new Timetracker_Model_TimeaccountFilter(array(array('field' => 'budget', 'operator' => 'greater', 'value' => 0), array('field' => 'number', 'operator' => 'startswith', 'value' => 'S-AB'))); $taController = Timetracker_Controller_Timeaccount::getInstance(); $tas = $taController->search($filter); $cfi = Tinebase_CustomField::getInstance(); $cfb = new Tinebase_Backend_Sql(array('modelName' => 'Tinebase_Model_CustomField_Value', 'tableName' => 'customfield')); $trBudget = $cfi->getCustomFieldByNameAndApplication('Timetracker', 'tr_budget'); if (!$trBudget) { die('No CustomField tr_budget found!'); } foreach ($tas as $ta) { echo 'Working on ' . $ta->title . PHP_EOL; $cf = new Tinebase_Model_CustomField_Value(array('record_id' => $ta->getId(), 'customfield_id' => $trBudget->getId(), 'value' => $ta->budget)); $cfb->create($cf); $ta->budget = NULL; $taController->update($ta); } echo PHP_EOL; echo 'done!' . PHP_EOL; }
/** * testCustomFieldDelete */ public function testCustomFieldDelete() { $this->testCustomFieldCreate(); $cfs = Tinebase_CustomField::getInstance()->getCustomFieldsForApplication('Addressbook'); $result = $cfs->filter('name', 'unittest_test')->getFirstRecord(); $deleted = Admin_Controller_Customfield::getInstance()->delete($result->getId()); $this->assertEquals(1, count($deleted)); }
/** * update to 3.16 * - add customfield_acl table */ public function update_15() { $declaration = new Setup_Backend_Schema_Table_Xml('<table> <name>customfield_acl</name> <version>1</version> <declaration> <field> <name>id</name> <type>text</type> <length>40</length> <notnull>true</notnull> </field> <field> <name>customfield_id</name> <type>text</type> <length>40</length> <notnull>true</notnull> </field> <field> <name>account_type</name> <type>enum</type> <value>anyone</value> <value>user</value> <value>group</value> <notnull>true</notnull> </field> <field> <name>account_id</name> <type>text</type> <length>40</length> <notnull>true</notnull> </field> <field> <name>account_grant</name> <type>text</type> <length>40</length> <notnull>true</notnull> </field> <index> <name>customfield_id-account-type-account_id-account_grant</name> <primary>true</primary> <field> <name>id</name> </field> <field> <name>customfield_id</name> </field> <field> <name>account_type</name> </field> <field> <name>account_id</name> </field> <field> <name>account_grant</name> </field> </index> <index> <name>id-account_type-account_id</name> <field> <name>customfield_id</name> </field> <field> <name>account_type</name> </field> <field> <name>account_id</name> </field> </index> <index> <name>customfield_acl::customfield_id--customfield_config::id</name> <field> <name>customfield_id</name> </field> <foreign>true</foreign> <reference> <table>customfield_config</table> <field>id</field> <ondelete>cascade</ondelete> </reference> </index> </declaration> </table>'); $this->createTable('customfield_acl', $declaration); // add grants to existing customfields $configBackend = new Tinebase_CustomField_Config(); $allCfConfigs = $configBackend->search(); foreach ($allCfConfigs as $cfConfig) { Tinebase_CustomField::getInstance()->setGrants($cfConfig, Tinebase_Model_CustomField_Grant::getAllGrants()); } $this->setApplicationVersion('Tinebase', '3.16'); }
/** * get custom field record * * @return Tinebase_Model_CustomField_Config */ protected function _getCustomField() { $record = new Tinebase_Model_CustomField_Config(array('application_id' => Tinebase_Application::getInstance()->getApplicationByName('Timetracker')->getId(), 'model' => 'Timetracker_Model_Timesheet', 'name' => Tinebase_Record_Abstract::generateUID(), 'definition' => array('label' => Tinebase_Record_Abstract::generateUID(), 'type' => 'string', 'uiconfig' => array('xtype' => Tinebase_Record_Abstract::generateUID(), 'length' => 10, 'group' => 'unittest', 'order' => 100)))); $result = Tinebase_CustomField::getInstance()->addCustomField($record); $this->_lastCreatedRecord = $result; return $result; }
/** * get by id * * @param string $_id * @param int $_containerId * @return Expressomail_Model_Account */ public function get($_id, $_containerId = NULL) { Tinebase_Core::setupCache(); $cache = Tinebase_Core::getCache(); $cacheId = $this->_createExpressomailModelAccountCacheId($_id); $record = $cache->load($cacheId); if ($record === FALSE) { $record = parent::get($_id, $_containerId); if ($record->user_id !== Tinebase_Core::getUser()->accountId) { $record = new Expressomail_Model_Account(); } if ($record->type == Expressomail_Model_Account::TYPE_SYSTEM) { $this->_addSystemAccountConfigValues($record); } if ($this->_checkSharedSeenSupport($record)) { $record->shared_seen_support = TRUE; $record->shared_seen = $this->_getSharedSeenValue($record); } if ($this->_resolveCustomFields && $record->has('customfields')) { Tinebase_CustomField::getInstance()->resolveRecordCustomFields($record); } $cache->save($record, $cacheId, array('expressomailAccount')); } return $record; }
/** * fetch one contact identified by $_userId * * @param int $_userId * @param boolean $_ignoreACL don't check acl grants * @return Addressbook_Model_Contact * @throws Addressbook_Exception_AccessDenied if user has no read grant * @throws Addressbook_Exception_NotFound if contact is hidden from addressbook * * @todo this is almost always called with ignoreACL = TRUE because contacts can be hidden from addressbook. * is this the way we want that? */ public function getContactByUserId($_userId, $_ignoreACL = FALSE) { $contact = $this->_backend->getByUserId($_userId); if ($_ignoreACL === FALSE) { if (empty($contact->container_id)) { throw new Addressbook_Exception_NotFound('Contact is hidden from addressbook (container id is empty).'); } if (!$this->_currentAccount->hasGrant($contact->container_id, Tinebase_Model_Grants::GRANT_READ)) { throw new Addressbook_Exception_AccessDenied('Read access to contact denied.'); } } if ($this->_resolveCustomFields && $contact->has('customfields')) { Tinebase_CustomField::getInstance()->resolveRecordCustomFields($contact); } return $contact; }
/** * sets the record related properties from user generated input. * * Input-filtering and validation by Zend_Filter_Input can enabled and disabled * * @param array $_data the new data to set * @throws Tinebase_Exception_Record_Validation when content contains invalid or missing data * * @todo remove custom fields handling (use Tinebase_Record_RecordSet for them) */ public function setFromArray(array $_data) { if ($this->convertDates === true) { $this->_convertISO8601ToDateTime($_data); } // set internal state to "not validated" $this->_isValidated = false; // get custom fields if ($this->has('customfields')) { $application = Tinebase_Application::getInstance()->getApplicationByName($this->_application); $customFields = Tinebase_CustomField::getInstance()->getCustomFieldsForApplication($application, get_class($this))->name; $recordCustomFields = array(); } else { $customFields = array(); } // make sure we run through the setters $bypassFilter = $this->bypassFilters; $this->bypassFilters = true; foreach ($_data as $key => $value) { if (isset($this->_validators[$key]) || array_key_exists($key, $this->_validators)) { $this->{$key} = $value; } else { if (in_array($key, $customFields)) { $recordCustomFields[$key] = $value; } } } if (!empty($recordCustomFields)) { $this->customfields = $recordCustomFields; } $this->bypassFilters = $bypassFilter; if ($this->bypassFilters !== true) { $this->isValid(true); } }
/** * appends sql to given select statement * * @param Zend_Db_Select $_select * @param Tinebase_Backend_Sql_Abstract $_backend * @throws Tinebase_Exception_UnexpectedValue */ public function appendFilterSql($_select, $_backend) { if ($this->_customfieldACLChecks) { // only search for ids for which the user has the required grants if (!$this->_isResolved) { $result = array(); foreach ($this->_requiredGrants as $grant) { $result = array_merge($result, Tinebase_CustomField::getInstance()->getCustomfieldConfigIdsByAcl($grant)); } $this->_validCustomfields = array_unique($result); $this->_isResolved = TRUE; } $db = Tinebase_Core::getDb(); $field = $db->quoteIdentifier('id'); $where = $db->quoteInto("{$field} IN (?)", empty($this->_validCustomfields) ? array('') : $this->_validCustomfields); $_select->where($where); } }
/** * tests if customfields gets saved properly */ public function testCustomFields() { $cfData = new Tinebase_Model_CustomField_Config(array('application_id' => Tinebase_Application::getInstance()->getApplicationByName('Calendar')->getId(), 'name' => 'unittest', 'model' => 'Calendar_Model_Event', 'definition' => array('label' => Tinebase_Record_Abstract::generateUID(), 'type' => 'string', 'uiconfig' => array('xtype' => Tinebase_Record_Abstract::generateUID(), 'length' => 10, 'group' => 'unittest', 'order' => 100)))); try { Tinebase_CustomField::getInstance()->addCustomField($cfData); } catch (Zend_Db_Statement_Exception $zdse) { // custom field already exists } $event = new Calendar_Model_Event(array('summary' => 'Abendessen', 'dtstart' => '2014-04-06 18:00:00', 'dtend' => '2014-04-06 19:00:00', 'description' => 'Guten Appetit', 'container_id' => $this->_getTestCalendar()->getId(), Tinebase_Model_Grants::GRANT_EDIT => true, 'customfields' => array('unittest' => 'Hello'))); $event = $this->_controller->create($event); $this->assertEquals('Hello', $event->customfields['unittest']); }
/** * delete containers, configs and other data of an application * * NOTE: if a table with foreign key constraints to applications is added, we need to make sure that the data is deleted here * * @param Tinebase_Model_Application $_applicationName * @return void */ public function removeApplicationData(Tinebase_Model_Application $_application) { $dataToDelete = array('container' => array('tablename' => ''), 'config' => array('tablename' => ''), 'customfield' => array('tablename' => ''), 'rights' => array('tablename' => 'role_rights'), 'definitions' => array('tablename' => 'importexport_definition'), 'filter' => array('tablename' => 'filter'), 'modlog' => array('tablename' => 'timemachine_modlog'), 'import' => array('tablename' => 'import')); $countMessage = ' Deleted'; $where = array($this->_getDb()->quoteInto($this->_getDb()->quoteIdentifier('application_id') . '= ?', $_application->getId())); foreach ($dataToDelete as $dataType => $info) { switch ($dataType) { case 'container': $count = Tinebase_Container::getInstance()->deleteContainerByApplicationId($_application->getId()); break; case 'config': $count = Tinebase_Config::getInstance()->deleteConfigByApplicationId($_application->getId()); break; case 'customfield': $count = Tinebase_CustomField::getInstance()->deleteCustomFieldsForApplication($_application->getId()); break; default: if ((isset($info['tablename']) || array_key_exists('tablename', $info)) && !empty($info['tablename'])) { try { $count = $this->_getDb()->delete(SQL_TABLE_PREFIX . $info['tablename'], $where); } catch (Zend_Db_Statement_Exception $zdse) { Tinebase_Exception::log($zdse); $count = 0; } } else { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' No tablename defined for ' . $dataType); $count = 0; } } $countMessage .= ' ' . $count . ' ' . $dataType . '(s) /'; } $countMessage .= ' for application ' . $_application->name; Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . $countMessage); }
/** * get custom field record * * @param string $name * @return Tinebase_Model_CustomField_Config */ protected function _createCustomField($name = 'Yomi Name') { $cfData = new Tinebase_Model_CustomField_Config(array('application_id' => Tinebase_Application::getInstance()->getApplicationByName('Addressbook')->getId(), 'name' => $name, 'model' => 'Addressbook_Model_Contact', 'definition' => array('label' => Tinebase_Record_Abstract::generateUID(), 'type' => 'string', 'uiconfig' => array('xtype' => Tinebase_Record_Abstract::generateUID(), 'length' => 10, 'group' => 'unittest', 'order' => 100)))); try { $result = Tinebase_CustomField::getInstance()->addCustomField($cfData); } catch (Zend_Db_Statement_Exception $zdse) { // customfield already exists $cfs = Tinebase_CustomField::getInstance()->getCustomFieldsForApplication('Addressbook'); $result = $cfs->filter('name', $name)->getFirstRecord(); } return $result; }
/** * add new customfield config * * needs args like this: * application="Addressbook" name="datefield" label="Date" model="Addressbook_Model_Contact" type="datefield" * @see Tinebase_Model_CustomField_Config for full list * * @param $_opts * @return boolean success */ public function addCustomfield(Zend_Console_Getopt $_opts) { if (!$this->_checkAdminRight()) { return FALSE; } // parse args $args = $_opts->getRemainingArgs(); $data = array(); foreach ($args as $idx => $arg) { list($key, $value) = explode('=', $arg); if ($key == 'application') { $key = 'application_id'; $value = Tinebase_Application::getInstance()->getApplicationByName($value)->getId(); } $data[$key] = $value; } $customfieldConfig = new Tinebase_Model_CustomField_Config($data); $cf = Tinebase_CustomField::getInstance()->addCustomField($customfieldConfig); echo "\nCreated customfield: "; print_r($cf->toArray()); echo "\n"; return TRUE; }
/** * Gets all entries * * @param string $_orderBy Order result by * @param string $_orderDirection Order direction - allowed are ASC and DESC * @throws Tinebase_Exception_InvalidArgument * @return Tinebase_Record_RecordSet */ public function getAll($_orderBy = 'id', $_orderDirection = 'ASC') { $this->_checkRight('get'); $records = $this->_backend->getAll($_orderBy, $_orderDirection); if ($this->resolveCustomfields()) { Tinebase_CustomField::getInstance()->resolveMultipleCustomfields($records); } return $records; }
/** * search / get custom field values * * @param array $filter filter array * @param array $paging pagination info * @return array */ public function searchCustomFieldValues($filter, $paging) { $result = $this->_search($filter, $paging, Tinebase_CustomField::getInstance(), 'Tinebase_Model_CustomField_ValueFilter'); return $result; }
/** * Sets up the fixture. * This method is called before a test is executed. * * @access protected */ protected function setUp() { $this->_transactionId = Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb()); $this->_instance = Tinebase_CustomField::getInstance(); }