/** * */ private function _getChangeLogFromRawData($pa_data, $pn_table_num, $pa_options = null) { //print "<pre>".print_r($pa_data, true)."</pre>\n"; $va_log_output = array(); $vs_blank_placeholder = '<' . _t('BLANK') . '>'; if (!$pa_options) { $pa_options = array(); } if (sizeof($pa_data)) { // // Init // $o_datamodel = Datamodel::load(); $va_change_types = array('I' => _t('Added'), 'U' => _t('Edited'), 'D' => _t('Deleted')); $vs_label_table_name = $vs_label_display_name = ''; $t_item = $o_datamodel->getInstanceByTableNum($pn_table_num, true); $vs_label_table_name = $vn_label_table_num = $vs_label_display_name = null; if (method_exists($t_item, 'getLabelTableName')) { $t_item_label = $t_item->getLabelTableInstance(); $vs_label_table_name = $t_item->getLabelTableName(); $vn_label_table_num = $t_item_label->tableNum(); $vs_label_display_name = $t_item_label->getProperty('NAME_SINGULAR'); } // // Group data by unit // $va_grouped_data = array(); foreach ($pa_data as $va_log_entry) { $va_grouped_data[$va_log_entry['unit_id']]['ca_table_num_' . $va_log_entry['logged_table_num']][] = $va_log_entry; } // // Process units // $va_attributes = array(); foreach ($va_grouped_data as $vn_unit_id => $va_log_entries_by_table) { foreach ($va_log_entries_by_table as $vs_table_key => $va_log_entries) { foreach ($va_log_entries as $va_log_entry) { $va_changes = array(); if (!is_array($va_log_entry['snapshot'])) { $va_log_entry['snapshot'] = array(); } // // Get date/time stamp for display // $vs_datetime = date("n/d/Y@g:i:sa T", $va_log_entry['log_datetime']); // // Get user name // $vs_user = $va_log_entry['fname'] . ' ' . $va_log_entry['lname']; $vs_email = $va_log_entry['email']; // The "logged" table/row is the row to which the change was actually applied // The "subject" table/row is the row to which the change is considered to have been made for workflow purposes. // // For example: if an entity is related to an object, strictly speaking the logging occurs on the ca_objects_x_entities // row (ca_objects_x_entities is the "logged" table), but the subject is ca_objects since it's only in the context of the // object (and probably the ca_entities row as well) that you can about the change. // $t_obj = $o_datamodel->getInstanceByTableNum($va_log_entry['logged_table_num'], true); // get instance for logged table if (!$t_obj) { continue; } $vs_subject_display_name = '???'; $vn_subject_row_id = null; $vn_subject_table_num = null; if (isset($pa_options['return_item_names']) && $pa_options['return_item_names']) { if (!($vn_subject_table_num = $va_log_entry['subject_table_num'])) { $vn_subject_table_num = $va_log_entry['logged_table_num']; $vn_subject_row_id = $va_log_entry['logged_row_id']; } else { $vn_subject_row_id = $va_log_entry['subject_row_id']; } if ($t_subject = $o_datamodel->getInstanceByTableNum($vn_subject_table_num, true)) { if ($t_subject->load($vn_subject_row_id)) { if (method_exists($t_subject, 'getLabelForDisplay')) { $vs_subject_display_name = $t_subject->getLabelForDisplay(false); } else { if ($vs_idno_field = $t_subject->getProperty('ID_NUMBERING_ID_FIELD')) { $vs_subject_display_name = $t_subject->getProperty('NAME_SINGULAR') . ' [' . $t_subject->get($vs_idno_field) . ']'; } else { $vs_subject_display_name = $t_subject->getProperty('NAME_SINGULAR') . ' [' . $vn_subject_row_id . ']'; } } } } } // // Get item changes // // --------------------------------------------------------------- // is this an intrinsic field? if ($pn_table_num == $va_log_entry['logged_table_num']) { foreach ($va_log_entry['snapshot'] as $vs_field => $vs_value) { $va_field_info = $t_obj->getFieldInfo($vs_field); if (isset($va_field_info['IDENTITY']) && $va_field_info['IDENTITY']) { continue; } if (isset($va_field_info['DISPLAY_TYPE']) && $va_field_info['DISPLAY_TYPE'] == DT_OMIT) { continue; } if (isset($va_field_info['DISPLAY_FIELD']) && is_array($va_field_info['DISPLAY_FIELD']) && ($va_disp_fields = $va_field_info['DISPLAY_FIELD'])) { // // Lookup value in related table // if (!$vs_value) { continue; } if (sizeof($va_disp_fields)) { $va_rel = $o_datamodel->getManyToOneRelations($t_obj->tableName(), $vs_field); $va_rel_values = array(); if ($t_rel_obj = $o_datamodel->getTableInstance($va_rel['one_table'], true)) { $t_rel_obj->load($vs_value); foreach ($va_disp_fields as $vs_display_field) { $va_tmp = explode('.', $vs_display_field); if (($vs_tmp = $t_rel_obj->get($va_tmp[1])) !== '') { $va_rel_values[] = $vs_tmp; } } } $vs_proc_val = join(', ', $va_rel_values); } } else { // Is field a foreign key? $va_keys = $o_datamodel->getManyToOneRelations($t_obj->tableName(), $vs_field); if (sizeof($va_keys)) { // yep, it's a foreign key $va_rel_values = array(); if ($t_rel_obj = $o_datamodel->getTableInstance($va_keys['one_table'], true)) { if ($t_rel_obj->load($vs_value)) { if (method_exists($t_rel_obj, 'getLabelForDisplay')) { $vs_proc_val = $t_rel_obj->getLabelForDisplay(false); } else { $va_disp_fields = $t_rel_obj->getProperty('LIST_FIELDS'); foreach ($va_disp_fields as $vs_display_field) { if (($vs_tmp = $t_rel_obj->get($vs_display_field)) !== '') { $va_rel_values[] = $vs_tmp; } } $vs_proc_val = join(' ', $va_rel_values); } if (!$vs_proc_val) { $vs_proc_val = '???'; } } else { $vs_proc_val = _t("Not set"); } } else { $vs_proc_val = _t('Non-existent'); } } else { // Adjust display of value for different field types switch ($va_field_info['FIELD_TYPE']) { case FT_BIT: $vs_proc_val = $vs_value ? 'Yes' : 'No'; break; default: $vs_proc_val = $vs_value; break; } // Adjust display of value for lists if ($va_field_info['LIST']) { $t_list = new ca_lists(); if ($t_list->load(array('list_code' => $va_field_info['LIST']))) { $vn_list_id = $t_list->getPrimaryKey(); $t_list_item = new ca_list_items(); if ($t_list_item->load(array('list_id' => $vn_list_id, 'item_value' => $vs_value))) { $vs_proc_val = $t_list_item->getLabelForDisplay(); } } } else { if ($va_field_info['BOUNDS_CHOICE_LIST']) { // TODO } } } } $va_changes[] = array('label' => $va_field_info['LABEL'], 'description' => strlen((string) $vs_proc_val) ? $vs_proc_val : $vs_blank_placeholder, 'value' => $vs_value); } } // --------------------------------------------------------------- // is this a label row? if ($va_log_entry['logged_table_num'] == $vn_label_table_num) { foreach ($va_log_entry['snapshot'] as $vs_field => $vs_value) { $va_changes[] = array('label' => $t_item_label->getFieldInfo($vs_field, 'LABEL'), 'description' => $vs_value); } } // --------------------------------------------------------------- // is this an attribute? if ($va_log_entry['logged_table_num'] == 3) { // attribute_values if ($t_element = ca_attributes::getElementInstance($va_log_entry['snapshot']['element_id'])) { if ($o_attr_val = Attribute::getValueInstance($t_element->get('datatype'))) { $o_attr_val->loadValueFromRow($va_log_entry['snapshot']); $vs_attr_val = $o_attr_val->getDisplayValue(); } else { $vs_attr_val = '?'; } // Convert list-based attributes to text if ($vn_list_id = $t_element->get('list_id')) { $t_list = new ca_lists(); $vs_attr_val = $t_list->getItemFromListForDisplayByItemID($vn_list_id, $vs_attr_val, true); } if (!$vs_attr_val) { $vs_attr_val = $vs_blank_placeholder; } $vs_label = $t_element->getLabelForDisplay(); $va_attributes[$va_log_entry['snapshot']['attribute_id']]['values'][] = array('label' => $vs_label, 'value' => $vs_attr_val); $va_changes[] = array('label' => $vs_label, 'description' => $vs_attr_val); } } // --------------------------------------------------------------- // is this a related (many-many) row? $va_keys = $o_datamodel->getOneToManyRelations($t_item->tableName(), $t_obj->tableName()); if (sizeof($va_keys) > 0) { if (method_exists($t_obj, 'getLeftTableNum')) { if ($t_obj->getLeftTableNum() == $t_item->tableNum()) { // other side of rel is on right $t_related_table = $o_datamodel->getInstanceByTableNum($t_obj->getRightTableNum(), true); $t_related_table->load($va_log_entry['snapshot'][$t_obj->getRightTableFieldName()]); } else { // other side of rel is on left $t_related_table = $o_datamodel->getInstanceByTableNum($t_obj->getLeftTableNum(), true); $t_related_table->load($va_log_entry['snapshot'][$t_obj->getLeftTableFieldName()]); } $t_rel = $o_datamodel->getInstanceByTableNum($t_obj->tableNum(), true); $va_changes[] = array('label' => caUcFirstUTF8Safe($t_related_table->getProperty('NAME_SINGULAR')), 'idno' => ($vs_idno_field = $t_related_table->getProperty('ID_NUMBERING_ID_FIELD')) ? $t_related_table->get($vs_idno_field) : null, 'description' => $t_related_table->getLabelForDisplay(), 'table_name' => $t_related_table->tableName(), 'table_num' => $t_related_table->tableNum(), 'row_id' => $t_related_table->getPrimaryKey(), 'rel_type_id' => $va_log_entry['snapshot']['type_id'], 'rel_typename' => $t_rel->getRelationshipTypename('ltor', $va_log_entry['snapshot']['type_id'])); } } // --------------------------------------------------------------- // record log line if (sizeof($va_changes)) { $va_log_output[$vn_unit_id][] = array('datetime' => $vs_datetime, 'user_fullname' => $vs_user, 'user_email' => $vs_email, 'user' => $vs_user . ' (' . $vs_email . ')', 'changetype_display' => $va_change_types[$va_log_entry['changetype']], 'changetype' => $va_log_entry['changetype'], 'changes' => $va_changes, 'subject' => $vs_subject_display_name, 'subject_id' => $vn_subject_row_id, 'subject_table_num' => $vn_subject_table_num, 'logged_table_num' => $va_log_entry['logged_table_num'], 'logged_table' => $t_obj->tableName(), 'logged_row_id' => $va_log_entry['logged_row_id']); } } } } } return $va_log_output; }
/** * */ public function editAttribute($pa_values, $pa_options = null) { if (!$this->getPrimaryKey()) { return null; } $vb_already_in_transaction = $this->inTransaction(); if (!$vb_already_in_transaction) { $o_trans = new Transaction(); $this->setTransaction($o_trans); } else { $o_trans = $this->getTransaction(); } unset(ca_attributes::$s_get_attributes_cache[$this->get('table_num') . '/' . $this->get('row_id')]); $this->setMode(ACCESS_WRITE); $this->set('locale_id', $pa_values['locale_id']); $this->update(); if ($this->numErrors()) { if (!$vb_already_in_transaction) { $o_trans->rollback(); } $vs_errors = join('; ', $this->getErrors()); $this->clearErrors(); $this->postError(1971, $vs_errors, 'ca_attributes->editAttribute()'); return false; } $t_attr_val = new ca_attribute_values(); $t_attr_val->purify($this->purify()); $t_attr_val->setTransaction($o_trans); $t_attr_val->setMode(ACCESS_WRITE); $t_element = ca_attributes::getElementInstance($this->get('element_id')); $va_elements = $t_element->getElementsInSet(); $va_attr_vals = $this->getAttributeValues(); foreach ($va_attr_vals as $o_attr_val) { $vn_element_id = intval($o_attr_val->getElementID()); if ($t_attr_val->load($o_attr_val->getValueID())) { if (isset($pa_values[$vn_element_id])) { $vm_value = $pa_values[$vn_element_id]; } else { $vm_value = $pa_values[$o_attr_val->getElementCode()]; } if ($t_attr_val->editValue($vm_value, $pa_options) === false) { $this->postError(1973, join('; ', $t_attr_val->getErrors()), 'ca_attributes->editAttribute()'); } foreach ($va_elements as $vn_i => $va_element_info) { if ($va_element_info['element_id'] == $vn_element_id) { unset($va_elements[$vn_i]); } } } } $vn_attribute_id = $this->getPrimaryKey(); // Add values that don't already exist (added after the fact?) foreach ($va_elements as $vn_index => $va_element) { if ($va_element['datatype'] == 0) { continue; } // skip containers $vn_element_id = $va_element['element_id']; if (isset($pa_values[$vn_element_id])) { $vm_value = $pa_values[$vn_element_id]; } else { $vm_value = $pa_values[$va_element['element_code']]; } if ($t_attr_val->addValue($vm_value, $va_element, $vn_attribute_id, $pa_options) === false) { $this->postError(1972, join('; ', $t_attr_val->getErrors()), 'ca_attributes->editAttribute()'); break; } } if ($this->numErrors()) { if (!$vb_already_in_transaction) { $o_trans->rollback(); } return false; } if (!$vb_already_in_transaction) { $o_trans->commit(); } return true; }
/** * */ public function delete($pb_delete_related = false, $pa_options = null, $pa_fields = null, $pa_table_list = null) { //$t_element = new ca_metadata_elements($this->get('element_id')); $t_element = ca_attributes::getElementInstance($this->get('element_id')); switch ($vn_data_type = $t_element->get('datatype')) { case 15: // FT_FILE $this->useBlobAsFileField(true); // force value_blob field to be treated as FT_FILE field by BaseModel break; case 16: // FT_MEDIA $this->useBlobAsMediaField(true); // force value_blob field to be treated as FT_MEDIA field by BaseModel break; default: // Reset value_blob field to default (FT_TEXT) – should already be that but we reset it just in case $this->useBlobAsMediaField(false); break; } return parent::delete($pb_delete_related, $pa_options, $pa_fields, $pa_table_list); }
public function testGetAttributeCount() { $t_element = ca_attributes::getElementInstance('internal_notes'); $this->opt_object->getDb()->dieOnError(true); $this->assertEquals(2, ca_attributes::getAttributeCount($this->opt_object->getDb(), $this->opt_object->tableNum(), $this->opt_object->getPrimaryKey(), $t_element->getPrimaryKey())); }