/** * Add items to specified set */ public function createSetFromResult() { global $g_ui_locale_id; $vs_mode = $this->request->getParameter('mode', pString); if ($vs_mode == 'from_checked') { $va_row_ids = explode(";", $this->request->getParameter('item_ids', pString)); } else { $va_row_ids = $this->opo_result_context->getResultList(); } $vs_set_code = null; $vn_added_items_count = 0; if (is_array($va_row_ids) && sizeof($va_row_ids)) { $t_model = $this->opo_datamodel->getInstanceByTableName($this->ops_tablename, true); $vs_set_name = $this->request->getParameter('set_name', pString); if (!$vs_set_name) { $vs_set_name = $this->opo_result_context->getSearchExpression(); } $t_set = new ca_sets(); $t_set->setMode(ACCESS_WRITE); $t_set->set('user_id', $this->request->getUserID()); $t_set->set('type_id', $this->request->config->get('ca_sets_default_type')); $t_set->set('table_num', $t_model->tableNum()); $t_set->set('set_code', $vs_set_code = mb_substr(preg_replace("![^A-Za-z0-9_\\-]+!", "_", $vs_set_name), 0, 100)); $t_set->insert(); if ($t_set->numErrors()) { $this->view->setVar('error', join("; ", $t_set->getErrors())); } $t_set->addLabel(array('name' => $vs_set_name), $g_ui_locale_id, null, true); $vn_added_items_count = $t_set->addItems($va_row_ids); $this->view->setVar('set_id', $t_set->getPrimaryKey()); $this->view->setVar('t_set', $t_set); } $this->view->setVar('set_name', $vs_set_name); $this->view->setVar('set_code', $vs_set_code); $this->view->setVar('num_items_added', $vn_added_items_count); $this->render('Results/ajax_create_set_from_result_json.php'); }
public function addItem() { global $g_ui_locale_id; // current locale_id for user if (!$this->request->isLoggedIn()) { $this->response->setRedirect(caNavUrl($this->request, '', 'LoginReg', 'form')); return; } if (!($t_set = $this->_getSet())) { # --- if there is not a set for this user, make a new set for them $t_new_set = new ca_sets(); $vn_new_set_id = null; $t_new_set->setMode(ACCESS_WRITE); $t_new_set->set('access', 0); $t_new_set->set('table_num', 57); // 57=ca_objects $t_list = new ca_lists(); $vn_set_id = $t_list->getItemIDFromList('set_types', $this->request->config->get('user_set_type')); $t_new_set->set('type_id', $vn_set_id); $t_new_set->set('user_id', $this->request->getUserID()); $t_new_set->set('set_code', $this->request->getUserID() . '_' . time()); // create new attribute $t_new_set->insert(); if (!$t_new_set->numErrors()) { if ($vn_new_set_id = $t_new_set->getPrimaryKey()) { $t_new_set->addLabel(array('name' => _t("Your first collection")), $g_ui_locale_id, null, true); // select the current set $this->request->user->setVar('current_set_id', $vn_new_set_id); //clear t_new_set object so form appears blank and load t_set so edit form is populated $t_new_set = new ca_sets(); $t_set = new ca_sets($vn_new_set_id); } } } if (!$t_set) { $va_errors[] = _t('Could not create collection for user'); } else { $pn_item_id = null; $pn_object_id = $this->request->getParameter('object_id', pInteger); if ($pn_item_id = $t_set->addItem($pn_object_id, array(), $this->request->getUserID())) { $va_errors = array(); $this->view->setVar('message', _t("Successfully added item")); } else { $va_errors[] = _t('Could not add item to collection'); } } $t_row = new ca_objects($pn_object_id); $this->view->setVar('errors', $va_errors); $this->index(); }
/** * Saves all bundles on the specified screen in the database by extracting * required data from the supplied request * $pm_screen can be a screen tag (eg. "Screen5") or a screen_id (eg. 5) * * Calls processBundlesBeforeBaseModelSave() method in subclass right before invoking insert() or update() on * the BaseModel, if the method is defined. Passes the following parameters to processBundlesBeforeBaseModelSave(): * array $pa_bundles An array of bundles to be saved * string $ps_form_prefix The form prefix * RequestHTTP $po_request The current request * array $pa_options Optional array of parameters; expected to be the same as that passed to saveBundlesForScreen() * * The processBundlesBeforeBaseModelSave() is useful for those odd cases where you need to do some processing before the basic * database record defined by the model (eg. intrinsic fields and hierarchy coding) is inserted or updated. You usually don't need * to use it. * * @param mixed $pm_screen * @param RequestHTTP $ps_request * @param array $pa_options Options are: * dryRun = Go through the motions of saving but don't actually write information to the database * batch = Process save in "batch" mode. Specifically this means honoring batch mode settings (add, replace, remove), skipping bundles that are not supported in batch mode and ignoring updates * existingRepresentationMap = an array of representation_ids key'ed on file path. If set saveBundlesForScreen() use link the specified representation to the row it is saving rather than processing the uploaded file. saveBundlesForScreen() will build the map as it goes, adding newly uploaded files. If you want it to process a file in a batch situation where it should be processed the first time and linked subsequently then pass an empty array here. saveBundlesForScreen() will use the empty array to build the map. */ public function saveBundlesForScreen($pm_screen, $po_request, &$pa_options) { $vb_we_set_transaction = false; $vs_form_prefix = caGetOption('formName', $pa_options, $po_request->getParameter('_formName', pString)); $vb_dryrun = caGetOption('dryRun', $pa_options, false); $vb_batch = caGetOption('batch', $pa_options, false); if (!$this->inTransaction()) { $this->setTransaction(new Transaction($this->getDb())); $vb_we_set_transaction = true; } else { if ($vb_dryrun) { $this->postError(799, _t('Cannot do dry run save when in transaction. Try again without setting a transaction.'), "BundlableLabelableBaseModelWithAttributes->saveBundlesForScreen()"); return false; } } $vb_read_only_because_deaccessioned = $this->hasField('is_deaccessioned') && (bool) $this->getAppConfig()->get('deaccession_dont_allow_editing') && (bool) $this->get('is_deaccessioned'); BaseModel::setChangeLogUnitID(); // get items on screen $t_ui = caGetOption('ui_instance', $pa_options, ca_editor_uis::loadDefaultUI($this->tableName(), $po_request, $this->getTypeID())); $va_bundle_lists = $this->getBundleListsForScreen($pm_screen, $po_request, $t_ui, $pa_options); // // Filter bundles to save if deaccessioned - only allow editing of the ca_objects_deaccession bundle // if ($vb_read_only_because_deaccessioned) { foreach ($va_bundle_lists['bundles'] as $vn_i => $va_bundle) { if ($va_bundle['bundle_name'] !== 'ca_objects_deaccession') { unset($va_bundle_lists['bundles'][$vn_i]); } } foreach ($va_bundle_lists['fields_by_type'] as $vs_type => $va_bundles) { foreach ($va_bundles as $vs_id => $vs_bundle_name) { if ($vs_bundle_name !== 'ca_objects_deaccession') { unset($va_bundle_lists['fields_by_type'][$vs_type][$vs_id]); } } } } $va_bundles = $va_bundle_lists['bundles']; $va_fields_by_type = $va_bundle_lists['fields_by_type']; // save intrinsic fields if (is_array($va_fields_by_type['intrinsic'])) { $vs_idno_field = $this->getProperty('ID_NUMBERING_ID_FIELD'); foreach ($va_fields_by_type['intrinsic'] as $vs_placement_code => $vs_f) { if ($vb_batch) { $vs_batch_mode = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_batch_mode", pString); if ($vs_batch_mode == '_disabled_') { continue; } } if (isset($_FILES["{$vs_placement_code}{$vs_form_prefix}{$vs_f}"]) && $_FILES["{$vs_placement_code}{$vs_form_prefix}{$vs_f}"]) { // media field $this->set($vs_f, $_FILES["{$vs_placement_code}{$vs_form_prefix}{$vs_f}"]['tmp_name'], array('original_filename' => $_FILES["{$vs_placement_code}{$vs_form_prefix}{$vs_f}"]['name'])); } else { switch ($vs_f) { case 'access': if ((bool) $this->getAppConfig()->get($this->tableName() . '_allow_access_inheritance') && $this->hasField('access_inherit_from_parent')) { $this->set('access_inherit_from_parent', $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}access_inherit_from_parent", pInteger)); } if (!(bool) $this->getAppConfig()->get($this->tableName() . '_allow_access_inheritance') || !$this->hasField('access_inherit_from_parent') || !(bool) $this->get('access_inherit_from_parent')) { $this->set('access', $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}access", pString)); } break; case $vs_idno_field: if ($this->opo_idno_plugin_instance) { $this->opo_idno_plugin_instance->setDb($this->getDb()); $this->set($vs_f, $vs_tmp = $this->opo_idno_plugin_instance->htmlFormValue($vs_idno_field)); } else { $this->set($vs_f, $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}{$vs_f}", pString)); } break; default: // Look for fully qualified intrinsic if (!strlen($vs_v = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}{$vs_f}", pString))) { // fall back to simple field name intrinsic spec - still used for "mandatory" fields such as type_id and parent_id $vs_v = $po_request->getParameter("{$vs_f}", pString); } $this->set($vs_f, $vs_v); break; } } if ($this->numErrors() > 0) { foreach ($this->errors() as $o_e) { switch ($o_e->getErrorNumber()) { case 795: // field conflicts foreach ($this->getFieldConflicts() as $vs_conflict_field) { $po_request->addActionError($o_e, $vs_conflict_field); } break; default: $po_request->addActionError($o_e, $vs_f); break; } } } } } // save attributes $va_inserted_attributes_by_element = array(); if (isset($va_fields_by_type['attribute']) && is_array($va_fields_by_type['attribute'])) { // // name of attribute request parameters are: // For new attributes // {$vs_form_prefix}_attribute_{element_set_id}_{element_id|'locale_id'}_new_{n} // ex. ObjectBasicForm_attribute_6_locale_id_new_0 or ObjectBasicForm_attribute_6_desc_type_new_0 // // For existing attributes: // {$vs_form_prefix}_attribute_{element_set_id}_{element_id|'locale_id'}_{attribute_id} // // look for newly created attributes; look for attributes to delete $va_inserted_attributes = array(); $reserved_elements = array(); foreach ($va_fields_by_type['attribute'] as $vs_placement_code => $vs_f) { $vs_element_set_code = preg_replace("/^ca_attribute_/", "", $vs_f); //does the attribute's datatype have a saveElement method - if so, use that instead $vs_element = $this->_getElementInstance($vs_element_set_code); $vn_element_id = $vs_element->getPrimaryKey(); $vs_element_datatype = $vs_element->get('datatype'); $vs_datatype = Attribute::getValueInstance($vs_element_datatype); if (method_exists($vs_datatype, 'saveElement')) { $reserved_elements[] = $vs_element; continue; } $va_attributes_to_insert = array(); $va_attributes_to_delete = array(); $va_locales = array(); $vs_batch_mode = $_REQUEST[$vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_id . '_batch_mode']; if ($vb_batch && $vs_batch_mode == '_delete_') { // Remove all attributes and continue $this->removeAttributes($vn_element_id, array('force' => true)); continue; } foreach ($_REQUEST as $vs_key => $vs_val) { // is it a newly created attribute? if (preg_match('/' . $vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_id . '_([\\w\\d\\-_]+)_new_([\\d]+)/', $vs_key, $va_matches)) { if ($vb_batch) { switch ($vs_batch_mode) { case '_disabled_': // skip continue 2; break; case '_add_': // just try to add attribute as in normal non-batch save // noop break; case '_replace_': // remove all existing attributes before trying to save $this->removeAttributes($vn_element_id, array('force' => true)); continue; break; } } $vn_c = intval($va_matches[2]); // yep - grab the locale and value $vn_locale_id = isset($_REQUEST[$vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_id . '_locale_id_new_' . $vn_c]) ? $_REQUEST[$vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_id . '_locale_id_new_' . $vn_c] : null; $va_inserted_attributes_by_element[$vn_element_id][$vn_c]['locale_id'] = $va_attributes_to_insert[$vn_c]['locale_id'] = $vn_locale_id; $va_inserted_attributes_by_element[$vn_element_id][$vn_c][$va_matches[1]] = $va_attributes_to_insert[$vn_c][$va_matches[1]] = $vs_val; } else { // is it a delete key? if (preg_match('/' . $vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_id . '_([\\d]+)_delete/', $vs_key, $va_matches)) { $vn_attribute_id = intval($va_matches[1]); $va_attributes_to_delete[$vn_attribute_id] = true; } } } // look for uploaded files as attributes foreach ($_FILES as $vs_key => $va_val) { if (preg_match('/' . $vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_id . '_locale_id_new_([\\d]+)/', $vs_key, $va_locale_matches)) { $vn_locale_c = intval($va_locale_matches[1]); $va_locales[$vn_locale_c] = $vs_val; continue; } // is it a newly created attribute? if (preg_match('/' . $vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_id . '_([\\w\\d\\-_]+)_new_([\\d]+)/', $vs_key, $va_matches)) { if (!$va_val['size']) { continue; } // skip empty files // yep - grab the value $vn_c = intval($va_matches[2]); $va_inserted_attributes_by_element[$vn_element_id][$vn_c]['locale_id'] = $va_attributes_to_insert[$vn_c]['locale_id'] = $va_locales[$vn_c]; $va_val['_uploaded_file'] = true; $va_inserted_attributes_by_element[$vn_element_id][$vn_c][$va_matches[1]] = $va_attributes_to_insert[$vn_c][$va_matches[1]] = $va_val; } } if (!$vb_batch) { // do deletes $this->clearErrors(); foreach ($va_attributes_to_delete as $vn_attribute_id => $vb_tmp) { $this->removeAttribute($vn_attribute_id, $vs_f, array('pending_adds' => $va_attributes_to_insert)); } } // do inserts foreach ($va_attributes_to_insert as $va_attribute_to_insert) { $this->clearErrors(); $this->addAttribute($va_attribute_to_insert, $vn_element_id, $vs_f); } if (!$vb_batch) { // check for attributes to update if (is_array($va_attrs = $this->getAttributesByElement($vn_element_id))) { $t_element = new ca_metadata_elements(); $va_attrs_update_list = array(); foreach ($va_attrs as $o_attr) { $this->clearErrors(); $vn_attribute_id = $o_attr->getAttributeID(); if (isset($va_inserted_attributes[$vn_attribute_id]) && $va_inserted_attributes[$vn_attribute_id]) { continue; } if (isset($va_attributes_to_delete[$vn_attribute_id]) && $va_attributes_to_delete[$vn_attribute_id]) { continue; } $vn_element_set_id = $o_attr->getElementID(); $va_attr_update = array('locale_id' => $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_set_id . '_locale_id_' . $vn_attribute_id, pString)); // // Check to see if there are any values in the element set that are not in the attribute we're editing // If additional sub-elements were added to the set after the attribute we're updating was created // those sub-elements will not have corresponding values returned by $o_attr->getValues() above. // Because we use the element_ids in those values to pull request parameters, if an element_id is missing // it effectively becomes invisible and cannot be set. This is a fairly unusual case but it happens, and when it does // it's really annoying. It would be nice and efficient to simply create the missing values at configuration time, but we wouldn't // know what to set the values to. So what we do is, after setting all of the values present in the attribute from the request, grab // the configuration for the element set and see if there are any elements in the set that we didn't get values for. // $va_sub_elements = $t_element->getElementsInSet($vn_element_set_id); foreach ($va_sub_elements as $vn_i => $va_element_info) { if ($va_element_info['datatype'] == 0) { continue; } //$vn_element_id = $o_attr_val->getElementID(); $vn_element_id = $va_element_info['element_id']; $vs_k = $vs_placement_code . $vs_form_prefix . '_attribute_' . $vn_element_set_id . '_' . $vn_element_id . '_' . $vn_attribute_id; if (isset($_FILES[$vs_k]) && ($va_val = $_FILES[$vs_k])) { if ($va_val['size'] > 0) { // is there actually a file? $va_val['_uploaded_file'] = true; $va_attr_update[$vn_element_id] = $va_val; continue; } } $vs_attr_val = $po_request->getParameter($vs_k, pString); $va_attr_update[$vn_element_id] = $vs_attr_val; } $this->clearErrors(); $this->editAttribute($vn_attribute_id, $vn_element_set_id, $va_attr_update, $vs_f); } } } } } if (!$vb_batch) { // hierarchy moves are not supported in batch mode if (is_array($va_fields_by_type['special'])) { foreach ($va_fields_by_type['special'] as $vs_placement_code => $vs_bundle) { if ($vs_bundle !== 'hierarchy_location') { continue; } $va_parent_tmp = explode("-", $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_new_parent_id", pString)); // Hierarchy browser sets new_parent_id param to "X" if user wants to extract item from hierarchy $vn_parent_id = ($vn_parent_id = array_pop($va_parent_tmp)) == 'X' ? -1 : (int) $vn_parent_id; if (sizeof($va_parent_tmp) > 0) { $vs_parent_table = array_pop($va_parent_tmp); } else { $vs_parent_table = $this->tableName(); } if ($this->getPrimaryKey() && $this->HIERARCHY_PARENT_ID_FLD && $vn_parent_id > 0) { if ($vs_parent_table == $this->tableName()) { $this->set($this->HIERARCHY_PARENT_ID_FLD, $vn_parent_id); } else { if ((bool) $this->getAppConfig()->get('ca_objects_x_collections_hierarchy_enabled') && $vs_parent_table == 'ca_collections' && $this->tableName() == 'ca_objects' && ($vs_coll_rel_type = $this->getAppConfig()->get('ca_objects_x_collections_hierarchy_relationship_type'))) { // link object to collection $this->removeRelationships('ca_collections', $vs_coll_rel_type); $this->set($this->HIERARCHY_PARENT_ID_FLD, null); $this->set($this->HIERARCHY_ID_FLD, $this->getPrimaryKey()); if (!$this->addRelationship('ca_collections', $vn_parent_id, $vs_coll_rel_type)) { $this->postError(2510, _t('Could not move object under collection: %1', join("; ", $this->getErrors())), "BundlableLabelableBaseModelWithAttributes->saveBundlesForScreen()"); } } } } else { if ($this->getPrimaryKey() && $this->HIERARCHY_PARENT_ID_FLD && $this->HIERARCHY_TYPE == __CA_HIER_TYPE_ADHOC_MONO__ && isset($_REQUEST["{$vs_placement_code}{$vs_form_prefix}_new_parent_id"]) && $vn_parent_id <= 0) { $this->set($this->HIERARCHY_PARENT_ID_FLD, null); $this->set($this->HIERARCHY_ID_FLD, $this->getPrimaryKey()); // Support for collection-object cross-table hierarchies if ((bool) $this->getAppConfig()->get('ca_objects_x_collections_hierarchy_enabled') && $this->tableName() == 'ca_objects' && ($vs_coll_rel_type = $this->getAppConfig()->get('ca_objects_x_collections_hierarchy_relationship_type')) && $vn_parent_id == -1) { // -1 = extract from hierarchy $this->removeRelationships('ca_collections', $vs_coll_rel_type); } } } break; } } } // // Call processBundlesBeforeBaseModelSave() method in sub-class, if it is defined. The method is passed // a list of bundles, the form prefix, the current request and the options passed to saveBundlesForScreen() – // everything needed to perform custom processing using the incoming form content that is being saved. // // A processBundlesBeforeBaseModelSave() method is rarely needed, but can be handy when you need to do something model-specific // right before the basic database record is committed via insert() (for new records) or update() (for existing records). // For example, the media in ca_object_representations is set in a "special" bundle, which provides a specialized media upload UI. Unfortunately "special's" // are handled after the basic database record is saved via insert() or update(), while the actual media must be set prior to the save. // processBundlesBeforeBaseModelSave() allows special logic in the ca_object_representations model to be invoked to set the media before the insert() or update(). // The "special" takes care of other functions after the insert()/update() // if (method_exists($this, "processBundlesBeforeBaseModelSave")) { $this->processBundlesBeforeBaseModelSave($va_bundles, $vs_form_prefix, $po_request, $pa_options); } $this->setMode(ACCESS_WRITE); $vb_is_insert = false; if ($this->getPrimaryKey()) { $this->update(); } else { $this->insert(); $vb_is_insert = true; } if ($this->numErrors() > 0) { $va_errors = array(); foreach ($this->errors() as $o_e) { switch ($o_e->getErrorNumber()) { case 2010: $po_request->addActionErrors(array($o_e), 'hierarchy_location'); break; case 795: // field conflict foreach ($this->getFieldConflicts() as $vs_conflict_field) { $po_request->addActionError($o_e, $vs_conflict_field); } break; case 1100: if ($vs_idno_field = $this->getProperty('ID_NUMBERING_ID_FIELD')) { $po_request->addActionError($o_e, $this->getProperty('ID_NUMBERING_ID_FIELD')); } break; default: $va_errors[] = $o_e; break; } } $po_request->addActionErrors($va_errors); if ($vb_is_insert) { BaseModel::unsetChangeLogUnitID(); if ($vb_we_set_transaction) { $this->removeTransaction(false); } return false; // bail on insert error } } if (!$this->getPrimaryKey()) { BaseModel::unsetChangeLogUnitID(); if ($vb_we_set_transaction) { $this->removeTransaction(false); } return false; } // bail if insert failed $this->clearErrors(); //save reserved elements - those with a saveElement method if (isset($reserved_elements) && is_array($reserved_elements)) { foreach ($reserved_elements as $res_element) { $res_element_id = $res_element->getPrimaryKey(); $res_element_datatype = $res_element->get('datatype'); $res_datatype = Attribute::getValueInstance($res_element_datatype); $res_datatype->saveElement($this, $res_element, $vs_form_prefix, $po_request); } } // save preferred labels if ($this->getProperty('LABEL_TABLE_NAME')) { $vb_check_for_dupe_labels = $this->_CONFIG->get('allow_duplicate_labels_for_' . $this->tableName()) ? false : true; $vb_error_inserting_pref_label = false; if (is_array($va_fields_by_type['preferred_label'])) { foreach ($va_fields_by_type['preferred_label'] as $vs_placement_code => $vs_f) { if (!$vb_batch) { // check for existing labels to update (or delete) $va_preferred_labels = $this->getPreferredLabels(null, false); foreach ($va_preferred_labels as $vn_item_id => $va_labels_by_locale) { foreach ($va_labels_by_locale as $vn_locale_id => $va_label_list) { foreach ($va_label_list as $va_label) { if ($vn_label_locale_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_Pref' . 'locale_id_' . $va_label['label_id'], pString)) { if (is_array($va_label_values = $this->getLabelUIValuesFromRequest($po_request, $vs_placement_code . $vs_form_prefix, $va_label['label_id'], true))) { if ($vb_check_for_dupe_labels && $this->checkForDupeLabel($vn_label_locale_id, $va_label_values)) { $this->postError(1125, _t('Value <em>%1</em> is already used and duplicates are not allowed', join("/", $va_label_values)), "BundlableLabelableBaseModelWithAttributes->saveBundlesForScreen()", $this->tableName() . '.preferred_labels'); $po_request->addActionErrors($this->errors(), 'preferred_labels'); continue; } $vn_label_type_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_Pref' . 'type_id_' . $va_label['label_id'], pInteger); $this->editLabel($va_label['label_id'], $va_label_values, $vn_label_locale_id, $vn_label_type_id, true); if ($this->numErrors()) { foreach ($this->errors() as $o_e) { switch ($o_e->getErrorNumber()) { case 795: // field conflicts $po_request->addActionError($o_e, 'preferred_labels'); break; default: $po_request->addActionError($o_e, $vs_f); break; } } } } } else { if ($po_request->getParameter($vs_placement_code . $vs_form_prefix . '_PrefLabel_' . $va_label['label_id'] . '_delete', pString)) { // delete $this->removeLabel($va_label['label_id']); } } } } } } // check for new labels to add foreach ($_REQUEST as $vs_key => $vs_value) { if (!preg_match('/' . $vs_placement_code . $vs_form_prefix . '_Pref' . 'locale_id_new_([\\d]+)/', $vs_key, $va_matches)) { continue; } if ($vb_batch) { $vs_batch_mode = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_Pref_batch_mode', pString); switch ($vs_batch_mode) { case '_disabled_': // skip continue 2; break; case '_replace_': // remove all existing preferred labels before trying to save $this->removeAllLabels(__CA_LABEL_TYPE_PREFERRED__); continue; case '_delete_': // remove all existing preferred labels $this->removeAllLabels(__CA_LABEL_TYPE_PREFERRED__); continue 2; case '_add_': break; } } $vn_c = intval($va_matches[1]); if ($vn_new_label_locale_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_Pref' . 'locale_id_new_' . $vn_c, pString)) { if (is_array($va_label_values = $this->getLabelUIValuesFromRequest($po_request, $vs_placement_code . $vs_form_prefix, 'new_' . $vn_c, true))) { // make sure we don't add multiple pref labels for one locale in batch mode if ($vb_batch && $vs_batch_mode == '_add_') { // first remove [BLANK] labels for this locale if there are any, as we are about to add a new one $va_labels_for_this_locale = $this->getPreferredLabels(array($vn_new_label_locale_id)); if (is_array($va_labels_for_this_locale)) { foreach ($va_labels_for_this_locale as $vn_id => $va_labels_by_locale) { foreach ($va_labels_by_locale as $vn_locale_id => $va_labels) { foreach ($va_labels as $vn_i => $va_label) { if (isset($va_label[$this->getLabelDisplayField()]) && $va_label[$this->getLabelDisplayField()] == '[' . _t('BLANK') . ']') { $this->removeLabel($va_label['label_id']); } } } } } // if there are non-[BLANK] labels for this locale, don't add this new one $va_labels_for_this_locale = $this->getPreferredLabels(array($vn_new_label_locale_id), true, array('forDisplay' => true)); if (is_array($va_labels_for_this_locale) && sizeof($va_labels_for_this_locale) > 0) { $this->postError(1125, _t('A preferred label for this locale already exists. Only one preferred label per locale is allowed.'), "BundlableLabelableBaseModelWithAttributes->saveBundlesForScreen()", $this->tableName() . '.preferred_labels'); $po_request->addActionErrors($this->errors(), $vs_f); $vb_error_inserting_pref_label = true; continue; } } if ($vb_check_for_dupe_labels && $this->checkForDupeLabel($vn_new_label_locale_id, $va_label_values)) { $this->postError(1125, _t('Value <em>%1</em> is already used and duplicates are not allowed', join("/", $va_label_values)), "BundlableLabelableBaseModelWithAttributes->saveBundlesForScreen()", $this->tableName() . '.preferred_labels'); $po_request->addActionErrors($this->errors(), 'preferred_labels'); $vb_error_inserting_pref_label = true; continue; } $vn_label_type_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_Pref' . 'type_id_new_' . $vn_c, pInteger); $this->addLabel($va_label_values, $vn_new_label_locale_id, $vn_label_type_id, true); if ($this->numErrors()) { $po_request->addActionErrors($this->errors(), $vs_f); $vb_error_inserting_pref_label = true; } } } } } } } // Add default label if needed (ie. if the user has failed to set at least one label or if they have deleted all existing labels) // This ensures at least one label is present for the record. If no labels are present then the // record may not be found in queries if ($this->getProperty('LABEL_TABLE_NAME')) { if ($vb_error_inserting_pref_label || !$this->addDefaultLabel($vn_new_label_locale_id)) { if (!$vb_error_inserting_pref_label) { $po_request->addActionErrors($this->errors(), 'preferred_labels'); } if ($vb_we_set_transaction) { $this->removeTransaction(false); } if ($vb_is_insert) { $this->_FIELD_VALUES[$this->primaryKey()] = null; // clear primary key, which doesn't actually exist since we rolled back the transaction foreach ($va_inserted_attributes_by_element as $vn_element_id => $va_failed_inserts) { // set attributes as "failed" (but with no error messages) so they stay set $this->setFailedAttributeInserts($vn_element_id, $va_failed_inserts); } } return false; } } unset($va_inserted_attributes_by_element); // save non-preferred labels if ($this->getProperty('LABEL_TABLE_NAME') && isset($va_fields_by_type['nonpreferred_label']) && is_array($va_fields_by_type['nonpreferred_label'])) { if (!$vb_batch) { foreach ($va_fields_by_type['nonpreferred_label'] as $vs_placement_code => $vs_f) { // check for existing labels to update (or delete) $va_nonpreferred_labels = $this->getNonPreferredLabels(null, false); foreach ($va_nonpreferred_labels as $vn_item_id => $va_labels_by_locale) { foreach ($va_labels_by_locale as $vn_locale_id => $va_label_list) { foreach ($va_label_list as $va_label) { if ($vn_label_locale_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_NPref' . 'locale_id_' . $va_label['label_id'], pString)) { if (is_array($va_label_values = $this->getLabelUIValuesFromRequest($po_request, $vs_placement_code . $vs_form_prefix, $va_label['label_id'], false))) { $vn_label_type_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_NPref' . 'type_id_' . $va_label['label_id'], pInteger); $this->editLabel($va_label['label_id'], $va_label_values, $vn_label_locale_id, $vn_label_type_id, false); if ($this->numErrors()) { foreach ($this->errors() as $o_e) { switch ($o_e->getErrorNumber()) { case 795: // field conflicts $po_request->addActionError($o_e, 'nonpreferred_labels'); break; default: $po_request->addActionError($o_e, $vs_f); break; } } } } } else { if ($po_request->getParameter($vs_placement_code . $vs_form_prefix . '_NPrefLabel_' . $va_label['label_id'] . '_delete', pString)) { // delete $this->removeLabel($va_label['label_id']); } } } } } } } // check for new labels to add foreach ($va_fields_by_type['nonpreferred_label'] as $vs_placement_code => $vs_f) { if ($vb_batch) { $vs_batch_mode = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_NPref_batch_mode', pString); switch ($vs_batch_mode) { case '_disabled_': // skip continue 2; break; case '_add_': // just try to add attribute as in normal non-batch save // noop break; case '_replace_': // remove all existing nonpreferred labels before trying to save $this->removeAllLabels(__CA_LABEL_TYPE_NONPREFERRED__); continue; case '_delete_': // remove all existing nonpreferred labels $this->removeAllLabels(__CA_LABEL_TYPE_NONPREFERRED__); continue 2; break; } } foreach ($_REQUEST as $vs_key => $vs_value) { if (!preg_match('/^' . $vs_placement_code . $vs_form_prefix . '_NPref' . 'locale_id_new_([\\d]+)/', $vs_key, $va_matches)) { continue; } $vn_c = intval($va_matches[1]); if ($vn_new_label_locale_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_NPref' . 'locale_id_new_' . $vn_c, pString)) { if (is_array($va_label_values = $this->getLabelUIValuesFromRequest($po_request, $vs_placement_code . $vs_form_prefix, 'new_' . $vn_c, false))) { $vn_new_label_type_id = $po_request->getParameter($vs_placement_code . $vs_form_prefix . '_NPref' . 'type_id_new_' . $vn_c, pInteger); $this->addLabel($va_label_values, $vn_new_label_locale_id, $vn_new_label_type_id, false); if ($this->numErrors()) { $po_request->addActionErrors($this->errors(), $vs_f); } } } } } } // save data in related tables if (isset($va_fields_by_type['related_table']) && is_array($va_fields_by_type['related_table'])) { foreach ($va_fields_by_type['related_table'] as $vs_placement_code => $vs_f) { $vn_table_num = $this->_DATAMODEL->getTableNum($vs_f); // get settings $va_bundle_settings = array(); foreach ($va_bundles as $va_bundle_info) { if ($va_bundle_info['placement_code'] == $vs_placement_code) { $va_bundle_settings = $va_bundle_info['settings']; break; } } switch ($vs_f) { # ------------------------------------- case 'ca_object_representations': // check for existing representations to update (or delete) $vs_prefix_stub = $vs_placement_code . $vs_form_prefix . '_'; $vb_allow_fetching_of_urls = (bool) $this->_CONFIG->get('allow_fetching_of_media_from_remote_urls'); $va_rep_ids_sorted = $va_rep_sort_order = explode(';', $po_request->getParameter($vs_prefix_stub . 'ObjectRepresentationBundleList', pString)); sort($va_rep_ids_sorted, SORT_NUMERIC); $va_reps = $this->getRepresentations(); if (!$vb_batch && is_array($va_reps)) { foreach ($va_reps as $vn_i => $va_rep) { $this->clearErrors(); if (strlen($po_request->getParameter($vs_prefix_stub . 'access_' . $va_rep['representation_id'], pInteger)) > 0) { if ($vb_allow_fetching_of_urls && ($vs_path = $_REQUEST[$vs_prefix_stub . 'media_url_' . $va_rep['representation_id']])) { $va_tmp = explode('/', $vs_path); $vs_original_name = array_pop($va_tmp); } else { $vs_path = $_FILES[$vs_prefix_stub . 'media_' . $va_rep['representation_id']]['tmp_name']; $vs_original_name = $_FILES[$vs_prefix_stub . 'media_' . $va_rep['representation_id']]['name']; } $vn_is_primary = $po_request->getParameter($vs_prefix_stub . 'is_primary_' . $va_rep['representation_id'], pString) != '' ? $po_request->getParameter($vs_prefix_stub . 'is_primary_' . $va_rep['representation_id'], pInteger) : null; $vn_locale_id = $po_request->getParameter($vs_prefix_stub . 'locale_id_' . $va_rep['representation_id'], pInteger); $vs_idno = $po_request->getParameter($vs_prefix_stub . 'idno_' . $va_rep['representation_id'], pString); $vn_access = $po_request->getParameter($vs_prefix_stub . 'access_' . $va_rep['representation_id'], pInteger); $vn_status = $po_request->getParameter($vs_prefix_stub . 'status_' . $va_rep['representation_id'], pInteger); $vs_rep_label = trim($po_request->getParameter($vs_prefix_stub . 'rep_label_' . $va_rep['representation_id'], pString)); //$vn_rep_type_id = $po_request->getParameter($vs_prefix_stub.'rep_type_id'.$va_rep['representation_id'], pInteger); // Get user-specified center point (images only) $vn_center_x = $po_request->getParameter($vs_prefix_stub . 'center_x_' . $va_rep['representation_id'], pString); $vn_center_y = $po_request->getParameter($vs_prefix_stub . 'center_y_' . $va_rep['representation_id'], pString); $vn_rank = null; if (($vn_rank_index = array_search($va_rep['representation_id'], $va_rep_sort_order)) !== false) { $vn_rank = $va_rep_ids_sorted[$vn_rank_index]; } $this->editRepresentation($va_rep['representation_id'], $vs_path, $vn_locale_id, $vn_status, $vn_access, $vn_is_primary, array('idno' => $vs_idno), array('original_filename' => $vs_original_name, 'rank' => $vn_rank, 'centerX' => $vn_center_x, 'centerY' => $vn_center_y)); if ($this->numErrors()) { //$po_request->addActionErrors($this->errors(), $vs_f, $va_rep['representation_id']); foreach ($this->errors() as $o_e) { switch ($o_e->getErrorNumber()) { case 795: // field conflicts $po_request->addActionError($o_e, $vs_f, $va_rep['representation_id']); break; default: $po_request->addActionError($o_e, $vs_f, $va_rep['representation_id']); break; } } } if ($vs_rep_label) { // // Set representation label // $t_rep = new ca_object_representations(); if ($this->inTransaction()) { $t_rep->setTransaction($this->getTransaction()); } global $g_ui_locale_id; if ($t_rep->load($va_rep['representation_id'])) { $t_rep->setMode(ACCESS_WRITE); $t_rep->replaceLabel(array('name' => $vs_rep_label), $g_ui_locale_id, null, true); if ($t_rep->numErrors()) { $po_request->addActionErrors($t_rep->errors(), $vs_f, $va_rep['representation_id']); } } } } else { // is it a delete key? $this->clearErrors(); if ($po_request->getParameter($vs_prefix_stub . $va_rep['representation_id'] . '_delete', pInteger) > 0) { // delete! $this->removeRepresentation($va_rep['representation_id']); if ($this->numErrors()) { $po_request->addActionErrors($this->errors(), $vs_f, $va_rep['representation_id']); } } } } } if ($vb_batch) { $vs_batch_mode = $_REQUEST[$vs_prefix_stub . 'batch_mode']; if ($vs_batch_mode == '_disabled_') { break; } if ($vs_batch_mode == '_replace_') { $this->removeAllRepresentations(); } if ($vs_batch_mode == '_delete_') { $this->removeAllRepresentations(); break; } } // check for new representations to add $va_file_list = $_FILES; foreach ($_REQUEST as $vs_key => $vs_value) { if (!preg_match('/^' . $vs_prefix_stub . 'media_url_new_([\\d]+)$/', $vs_key, $va_matches)) { continue; } $va_file_list[$vs_key] = array('url' => $vs_value); } foreach ($va_file_list as $vs_key => $va_values) { $this->clearErrors(); if (!preg_match('/^' . $vs_prefix_stub . 'media_new_([\\d]+)$/', $vs_key, $va_matches) && ($vb_allow_fetching_of_urls && !preg_match('/^' . $vs_prefix_stub . 'media_url_new_([\\d]+)$/', $vs_key, $va_matches) || !$vb_allow_fetching_of_urls)) { continue; } if ($vs_upload_type = $po_request->getParameter($vs_prefix_stub . 'upload_typenew_' . $va_matches[1], pString)) { $po_request->user->setVar('defaultRepresentationUploadType', $vs_upload_type); } $vn_type_id = $po_request->getParameter($vs_prefix_stub . 'type_id_new_' . $va_matches[1], pInteger); if ($vn_existing_rep_id = $po_request->getParameter($vs_prefix_stub . 'idnew_' . $va_matches[1], pInteger)) { $this->addRelationship('ca_object_representations', $vn_existing_rep_id, $vn_type_id); } else { if ($vb_allow_fetching_of_urls && ($vs_path = $va_values['url'])) { $va_tmp = explode('/', $vs_path); $vs_original_name = array_pop($va_tmp); } else { $vs_path = $va_values['tmp_name']; $vs_original_name = $va_values['name']; } if (!$vs_path) { continue; } $vn_rep_type_id = $po_request->getParameter($vs_prefix_stub . 'rep_type_id_new_' . $va_matches[1], pInteger); if (!$vn_rep_type_id && !($vn_rep_type_id = caGetDefaultItemID('object_representation_types'))) { require_once __CA_MODELS_DIR__ . '/ca_lists.php'; $t_list = new ca_lists(); if (is_array($va_rep_type_ids = $t_list->getItemsForList('object_representation_types', array('idsOnly' => true, 'enabledOnly' => true)))) { $vn_rep_type_id = array_shift($va_rep_type_ids); } } if (is_array($pa_options['existingRepresentationMap']) && isset($pa_options['existingRepresentationMap'][$vs_path]) && $pa_options['existingRepresentationMap'][$vs_path]) { $this->addRelationship('ca_object_representations', $pa_options['existingRepresentationMap'][$vs_path], $vn_type_id); break; } $vs_rep_label = trim($po_request->getParameter($vs_prefix_stub . 'rep_label_new_' . $va_matches[1], pString)); $vn_locale_id = $po_request->getParameter($vs_prefix_stub . 'locale_id_new_' . $va_matches[1], pInteger); $vs_idno = $po_request->getParameter($vs_prefix_stub . 'idno_new_' . $va_matches[1], pString); $vn_status = $po_request->getParameter($vs_prefix_stub . 'status_new_' . $va_matches[1], pInteger); $vn_access = $po_request->getParameter($vs_prefix_stub . 'access_new_' . $va_matches[1], pInteger); $vn_is_primary = $po_request->getParameter($vs_prefix_stub . 'is_primary_new_' . $va_matches[1], pInteger); // Get user-specified center point (images only) $vn_center_x = $po_request->getParameter($vs_prefix_stub . 'center_x_new_' . $va_matches[1], pString); $vn_center_y = $po_request->getParameter($vs_prefix_stub . 'center_y_new_' . $va_matches[1], pString); $t_rep = $this->addRepresentation($vs_path, $vn_rep_type_id, $vn_locale_id, $vn_status, $vn_access, $vn_is_primary, array('name' => $vs_rep_label, 'idno' => $vs_idno), array('original_filename' => $vs_original_name, 'returnRepresentation' => true, 'centerX' => $vn_center_x, 'centerY' => $vn_center_y, 'type_id' => $vn_type_id)); // $vn_type_id = *relationship* type_id (as opposed to representation type) if ($this->numErrors()) { $po_request->addActionErrors($this->errors(), $vs_f, 'new_' . $va_matches[1]); } else { if ($t_rep && is_array($pa_options['existingRepresentationMap'])) { $pa_options['existingRepresentationMap'][$vs_path] = $t_rep->getPrimaryKey(); } } } } break; # ------------------------------------- # ------------------------------------- case 'ca_entities': case 'ca_places': case 'ca_objects': case 'ca_collections': case 'ca_occurrences': case 'ca_list_items': case 'ca_object_lots': case 'ca_storage_locations': case 'ca_loans': case 'ca_movements': case 'ca_tour_stops': $this->_processRelated($po_request, $vs_f, $vs_form_prefix, $vs_placement_code, array('batch' => $vb_batch, 'settings' => $va_bundle_settings)); break; # ------------------------------------- # ------------------------------------- case 'ca_representation_annotations': if ($vb_batch) { break; } // not supported in batch mode $this->_processRepresentationAnnotations($po_request, $vs_form_prefix, $vs_placement_code); break; # ------------------------------------- } } } // save data for "specials" if (isset($va_fields_by_type['special']) && is_array($va_fields_by_type['special'])) { foreach ($va_fields_by_type['special'] as $vs_placement_code => $vs_f) { // get settings $va_bundle_settings = array(); foreach ($va_bundles as $va_bundle_info) { if ('P' . $va_bundle_info['placement_id'] == $vs_placement_code) { $va_bundle_settings = $va_bundle_info['settings']; break; } } switch ($vs_f) { # ------------------------------------- // This bundle is only available when editing objects of type ca_representation_annotations case 'ca_representation_annotation_properties': if ($vb_batch) { break; } // not supported in batch mode if (!$this->useInEditor()) { break; } foreach ($this->getPropertyList() as $vs_property) { $this->setPropertyValue($vs_property, $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}{$vs_property}", pString)); } if (!$this->validatePropertyValues()) { $po_request->addActionErrors($this->errors(), 'ca_representation_annotation_properties', 'general'); } $this->update(); break; # ------------------------------------- // This bundle is only available for types which support set membership # ------------------------------------- // This bundle is only available for types which support set membership case 'ca_sets': // check for existing labels to delete (no updating supported) require_once __CA_MODELS_DIR__ . '/ca_sets.php'; require_once __CA_MODELS_DIR__ . '/ca_set_items.php'; $t_set = new ca_sets(); if (!$vb_batch) { $va_sets = caExtractValuesByUserLocale($t_set->getSetsForItem($this->tableNum(), $this->getPrimaryKey(), array('user_id' => $po_request->getUserID()))); foreach ($va_sets as $vn_set_id => $va_set_info) { $vn_item_id = $va_set_info['item_id']; if ($po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_set_id_{$vn_item_id}_delete", pString)) { // delete $t_set->load($va_set_info['set_id']); $t_set->removeItem($this->getPrimaryKey(), $po_request->getUserID()); // remove *all* instances of the item in the set, not just the specified id if ($t_set->numErrors()) { $po_request->addActionErrors($t_set->errors(), $vs_f); } } } } if ($vb_batch) { $vs_batch_mode = $_REQUEST["{$vs_placement_code}{$vs_form_prefix}_batch_mode"]; if ($vs_batch_mode == '_disabled_') { break; } if ($vs_batch_mode == '_replace_') { $t_set->removeItemFromAllSets($this->tableNum(), $this->getPrimaryKey()); } if ($vs_batch_mode == '_delete_') { $t_set->removeItemFromAllSets($this->tableNum(), $this->getPrimaryKey()); break; } } foreach ($_REQUEST as $vs_key => $vs_value) { if (!preg_match("/{$vs_placement_code}{$vs_form_prefix}_set_id_new_([\\d]+)/", $vs_key, $va_matches)) { continue; } $vn_c = intval($va_matches[1]); if ($vn_new_set_id = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_set_id_new_{$vn_c}", pString)) { $t_set->load($vn_new_set_id); $t_set->addItem($this->getPrimaryKey(), null, $po_request->getUserID()); if ($t_set->numErrors()) { $po_request->addActionErrors($t_set->errors(), $vs_f); } } } break; # ------------------------------------- // This bundle is only available for types which support set membership # ------------------------------------- // This bundle is only available for types which support set membership case 'ca_set_items': if ($vb_batch) { break; } // not supported in batch mode // check for existing labels to delete (no updating supported) require_once __CA_MODELS_DIR__ . '/ca_sets.php'; require_once __CA_MODELS_DIR__ . '/ca_set_items.php'; $va_rids = explode(';', $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}setRowIDList", pString)); $this->reorderItems($va_rids, array('user_id' => $po_request->getUserID(), 'treatRowIDsAsRIDs' => true, 'deleteExcludedItems' => true)); break; # ------------------------------------- // This bundle is only available for ca_search_forms # ------------------------------------- // This bundle is only available for ca_search_forms case 'ca_search_form_elements': if ($vb_batch) { break; } // not supported in batch mode // save settings $va_settings = $this->getAvailableSettings(); foreach ($va_settings as $vs_setting => $va_setting_info) { if (isset($_REQUEST['setting_' . $vs_setting])) { $vs_setting_val = $po_request->getParameter('setting_' . $vs_setting, pString); $this->setSetting($vs_setting, $vs_setting_val); $this->update(); } } break; # ------------------------------------- // This bundle is only available for ca_bundle_displays # ------------------------------------- // This bundle is only available for ca_bundle_displays case 'ca_bundle_display_placements': if ($vb_batch) { break; } // not supported in batch mode $this->savePlacementsFromHTMLForm($po_request, $vs_form_prefix, $vs_placement_code); break; # ------------------------------------- // This bundle is only available for ca_bundle_displays # ------------------------------------- // This bundle is only available for ca_bundle_displays case 'ca_bundle_display_type_restrictions': if ($vb_batch) { break; } // not supported in batch mode $this->saveTypeRestrictionsFromHTMLForm($po_request, $vs_form_prefix, $vs_placement_code); break; # ------------------------------------- // This bundle is only available for ca_search_forms # ------------------------------------- // This bundle is only available for ca_search_forms case 'ca_search_form_placements': if ($vb_batch) { break; } // not supported in batch mode $this->savePlacementsFromHTMLForm($po_request, $vs_form_prefix, $vs_placement_code); break; # ------------------------------------- // This bundle is only available for ca_editor_ui # ------------------------------------- // This bundle is only available for ca_editor_ui case 'ca_editor_ui_screens': if ($vb_batch) { break; } // not supported in batch mode global $g_ui_locale_id; require_once __CA_MODELS_DIR__ . '/ca_editor_ui_screens.php'; $va_screen_ids = explode(';', $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_ScreenBundleList", pString)); foreach ($_REQUEST as $vs_key => $vs_val) { if (is_array($vs_val)) { continue; } if (!($vs_val = trim($vs_val))) { continue; } if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_name_new_([\\d]+)\$!", $vs_key, $va_matches)) { if (!($t_screen = $this->addScreen($vs_val, $g_ui_locale_id, 'screen_' . $this->getPrimaryKey() . '_' . $va_matches[1]))) { break; } if ($vn_fkey = array_search("new_" . $va_matches[1], $va_screen_ids)) { $va_screen_ids[$vn_fkey] = $t_screen->getPrimaryKey(); } else { $va_screen_ids[] = $t_screen->getPrimaryKey(); } continue; } if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_([\\d]+)_delete\$!", $vs_key, $va_matches)) { $this->removeScreen($va_matches[1]); if ($vn_fkey = array_search($va_matches[1], $va_screen_ids)) { unset($va_screen_ids[$vn_fkey]); } } } $this->reorderScreens($va_screen_ids); break; # ------------------------------------- // This bundle is only available for ca_editor_ui_screens # ------------------------------------- // This bundle is only available for ca_editor_ui_screens case 'ca_editor_ui_bundle_placements': if ($vb_batch) { break; } // not supported in batch mode $this->savePlacementsFromHTMLForm($po_request, $vs_form_prefix, $vs_placement_code); break; # ------------------------------------- // This bundle is only available for ca_editor_uis # ------------------------------------- // This bundle is only available for ca_editor_uis case 'ca_editor_ui_type_restrictions': if ($vb_batch) { break; } // not supported in batch mode $this->saveTypeRestrictionsFromHTMLForm($po_request, $vs_form_prefix, $vs_placement_code); break; # ------------------------------------- // This bundle is only available for ca_editor_ui_screens # ------------------------------------- // This bundle is only available for ca_editor_ui_screens case 'ca_editor_ui_screen_type_restrictions': if ($vb_batch) { break; } // not supported in batch mode $this->saveTypeRestrictionsFromHTMLForm($po_request, $vs_form_prefix, $vs_placement_code); break; # ------------------------------------- // This bundle is only available for ca_tours # ------------------------------------- // This bundle is only available for ca_tours case 'ca_tour_stops_list': if ($vb_batch) { break; } // not supported in batch mode global $g_ui_locale_id; require_once __CA_MODELS_DIR__ . '/ca_tour_stops.php'; $va_stop_ids = explode(';', $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_StopBundleList", pString)); foreach ($_REQUEST as $vs_key => $vs_val) { if (!($vs_val = trim($vs_val))) { continue; } if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_name_new_([\\d]+)\$!", $vs_key, $va_matches)) { $vn_type_id = $_REQUEST["{$vs_placement_code}{$vs_form_prefix}_type_id_new_" . $va_matches[1]]; if (!($t_stop = $this->addStop($vs_val, $vn_type_id, $g_ui_locale_id, mb_substr(preg_replace('![^A-Za-z0-9_]+!', '_', $vs_val), 0, 255)))) { break; } if ($vn_fkey = array_search("new_" . $va_matches[1], $va_stop_ids)) { $va_stop_ids[$vn_fkey] = $t_stop->getPrimaryKey(); } else { $va_stop_ids[] = $t_stop->getPrimaryKey(); } continue; } if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_([\\d]+)_delete\$!", $vs_key, $va_matches)) { $this->removeStop($va_matches[1]); if ($vn_fkey = array_search($va_matches[1], $va_stop_ids)) { unset($va_stop_ids[$vn_fkey]); } } } $this->reorderStops($va_stop_ids); break; # ------------------------------------- # ------------------------------------- case 'ca_user_groups': if ($vb_batch) { break; } // not supported in batch mode if (!$po_request->user->canDoAction('is_administrator') && $po_request->getUserID() != $this->get('user_id')) { break; } // don't save if user is not owner require_once __CA_MODELS_DIR__ . '/ca_user_groups.php'; $va_groups_to_set = $va_group_effective_dates = array(); foreach ($_REQUEST as $vs_key => $vs_val) { if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_id(.*)\$!", $vs_key, $va_matches)) { $vs_effective_date = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_effective_date_" . $va_matches[1], pString); $vn_group_id = (int) $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_id" . $va_matches[1], pInteger); $vn_access = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_access_" . $va_matches[1], pInteger); if ($vn_access > 0) { $va_groups_to_set[$vn_group_id] = $vn_access; $va_group_effective_dates[$vn_group_id] = $vs_effective_date; } } } $this->setUserGroups($va_groups_to_set, $va_group_effective_dates, array('user_id' => $po_request->getUserID())); break; # ------------------------------------- # ------------------------------------- case 'ca_users': if ($vb_batch) { break; } // not supported in batch mode if (!$po_request->user->canDoAction('is_administrator') && $po_request->getUserID() != $this->get('user_id')) { break; } // don't save if user is not owner require_once __CA_MODELS_DIR__ . '/ca_users.php'; $va_users_to_set = $va_user_effective_dates = array(); foreach ($_REQUEST as $vs_key => $vs_val) { if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_id(.*)\$!", $vs_key, $va_matches)) { $vs_effective_date = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_effective_date_" . $va_matches[1], pString); $vn_user_id = (int) $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_id" . $va_matches[1], pInteger); $vn_access = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_access_" . $va_matches[1], pInteger); if ($vn_access > 0) { $va_users_to_set[$vn_user_id] = $vn_access; $va_user_effective_dates[$vn_user_id] = $vs_effective_date; } } } $this->setUsers($va_users_to_set, $va_user_effective_dates); break; # ------------------------------------- # ------------------------------------- case 'settings': if ($vb_batch) { break; } // not supported in batch mode $this->setSettingsFromHTMLForm($po_request, array('id' => $vs_form_prefix . '_', 'placement_code' => $vs_placement_code)); break; # ------------------------------- // This bundle is only available when editing objects of type ca_object_representations # ------------------------------- // This bundle is only available when editing objects of type ca_object_representations case 'ca_object_representations_media_display': if ($vb_batch) { break; } // not supported in batch mode $va_versions_to_process = null; if ($vb_use_options = (bool) $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_derivative_options_selector", pInteger)) { // update only specified versions $va_versions_to_process = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_set_versions", pArray); } if (!is_array($va_versions_to_process) || !sizeof($va_versions_to_process)) { $va_versions_to_process = array('_all'); } if ($vb_use_options && $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_derivative_options_mode", pString) == 'timecode') { // timecode if (!(string) ($vs_timecode = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_derivative_options_mode_timecode_value", pString))) { $vs_timecode = "1s"; } // $o_media = new Media(); if ($o_media->read($this->getMediaPath('media', 'original'))) { $va_files = $o_media->writePreviews(array('force' => true, 'outputDirectory' => $this->_CONFIG->get("taskqueue_tmp_directory"), 'minNumberOfFrames' => 1, 'maxNumberOfFrames' => 1, 'startAtTime' => $vs_timecode, 'endAtTime' => $vs_timecode, 'width' => 720, 'height' => 540)); if (sizeof($va_files)) { $this->set('media', array_shift($va_files)); } } } else { if ($vb_use_options && $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_derivative_options_mode", pString) == 'page') { if (!(int) ($vn_page = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_derivative_options_mode_page_value", pInteger))) { $vn_page = 1; } // $o_media = new Media(); if ($o_media->read($this->getMediaPath('media', 'original'))) { $va_files = $o_media->writePreviews(array('force' => true, 'outputDirectory' => $this->_CONFIG->get("taskqueue_tmp_directory"), 'numberOfPages' => 1, 'startAtPage' => $vn_page, 'width' => 2048, 'height' => 2048)); if (sizeof($va_files)) { $this->set('media', array_shift($va_files)); } } } else { // process file as new upload $vs_key = "{$vs_placement_code}{$vs_form_prefix}_url"; if (($vs_media_url = trim($po_request->getParameter($vs_key, pString))) && isURL($vs_media_url)) { $this->set('media', $vs_media_url); } else { $vs_key = "{$vs_placement_code}{$vs_form_prefix}_media"; if (isset($_FILES[$vs_key])) { $this->set('media', $_FILES[$vs_key]['tmp_name'], array('original_filename' => $_FILES[$vs_key]['name'])); } } } } if ($this->changed('media')) { $this->update($vs_version != '_all' ? array('updateOnlyMediaVersions' => $va_versions_to_process) : array()); if ($this->numErrors()) { $po_request->addActionErrors($this->errors(), 'ca_object_representations_media_display', 'general'); } } break; # ------------------------------- // This bundle is only available when editing objects of type ca_object_representations # ------------------------------- // This bundle is only available when editing objects of type ca_object_representations case 'ca_object_representation_captions': if ($vb_batch) { return null; } // not supported in batch mode $va_users_to_set = array(); foreach ($_REQUEST as $vs_key => $vs_val) { if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_locale_id(.*)\$!", $vs_key, $va_matches)) { $vn_locale_id = (int) $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_locale_id" . $va_matches[1], pInteger); $this->addCaptionFile($_FILES["{$vs_placement_code}{$vs_form_prefix}_caption_file" . $va_matches[1]]['tmp_name'], $vn_locale_id, array('originalFilename' => $_FILES["{$vs_placement_code}{$vs_form_prefix}_captions_caption_file" . $va_matches[1]]['name'])); } else { // any to delete? if (preg_match("!^{$vs_placement_code}{$vs_form_prefix}_([\\d]+)_delete\$!", $vs_key, $va_matches)) { $this->removeCaptionFile((int) $va_matches[1]); } } } break; # ------------------------------- // This bundle is only available for relationships that include an object on one end # ------------------------------- // This bundle is only available for relationships that include an object on one end case 'ca_object_representation_chooser': if ($vb_batch) { return null; } // not supported in batch mode if (!is_array($va_rep_ids = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}", pArray))) { $va_rep_ids = array(); } if ($vs_element_code = caGetOption(array('elementCode', 'element_code'), $va_bundle_settings, null)) { if (!is_array($va_current_rep_ids = $this->get($this->tableName() . "." . $vs_element_code, array('returnAsArray' => true, 'idsOnly' => true)))) { $va_current_rep_ids = $va_current_rep_id_with_structure = array(); } else { $va_current_rep_id_with_structure = $this->get($this->tableName() . "." . $vs_element_code, array('returnWithStructure' => true, 'idsOnly' => true)); } $va_rep_to_attr_id = array(); foreach ($va_rep_ids as $vn_rep_id) { if (in_array($vn_rep_id, $va_current_rep_ids)) { continue; } $this->addAttribute(array($vs_element_code => $vn_rep_id), $vs_element_code); } foreach ($va_current_rep_id_with_structure as $vn_id => $va_vals_by_attr_id) { foreach ($va_vals_by_attr_id as $vn_attribute_id => $va_val) { if (!in_array($va_val[$vs_element_code], $va_rep_ids)) { $this->removeAttribute($vn_attribute_id); } } } $this->update(); } break; # ------------------------------- // This bundle is only available for objects # ------------------------------- // This bundle is only available for objects case 'ca_objects_location': if ($vb_batch) { return null; } // not supported in batch mode if (!$po_request->user->canDoAction('can_edit_ca_objects')) { break; } if ($vn_location_id = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_location_idnew_0", pInteger)) { if (is_array($va_relationship_types = caGetOption('ca_storage_locations_relationshipType', $va_bundle_settings, null)) && ($vn_relationship_type_id = array_shift($va_relationship_types))) { $this->addRelationship('ca_storage_locations', $vn_location_id, $vn_relationship_type_id, null, null, null, null, array('allowDuplicates' => true)); if ($this->numErrors()) { $po_request->addActionErrors($this->errors(), 'ca_objects_location', 'general'); } } } break; # ------------------------------- // This bundle is only available for objects # ------------------------------- // This bundle is only available for objects case 'ca_objects_history': if ($vb_batch) { return null; } // not supported in batch mode if (!$po_request->user->canDoAction('can_edit_ca_objects')) { break; } // set storage location if ($vn_location_id = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_location_idnew_0", pInteger)) { if (is_array($va_relationship_types = caGetOption('ca_storage_locations_showRelationshipTypes', $va_bundle_settings, null)) && ($vn_relationship_type_id = array_shift($va_relationship_types))) { $this->addRelationship('ca_storage_locations', $vn_location_id, $vn_relationship_type_id, null, null, null, null, array('allowDuplicates' => true)); if ($this->numErrors()) { $po_request->addActionErrors($this->errors(), 'ca_objects_history', 'general'); } } } // set loan if ($vn_loan_id = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_loan_idnew_0", pInteger)) { if ($vn_loan_type_id = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}_loan_type_idnew_0", pInteger)) { $this->addRelationship('ca_loans', $vn_loan_id, $vn_loan_type_id); if ($this->numErrors()) { $po_request->addActionErrors($this->errors(), 'ca_objects_history', 'general'); } } } break; # ------------------------------- // This bundle is only available for objects # ------------------------------- // This bundle is only available for objects case 'ca_objects_deaccession': // object deaccession information if (!$vb_batch && !$this->getPrimaryKey()) { return null; } // not supported for new records if (!$po_request->user->canDoAction('can_edit_ca_objects')) { break; } $this->set('is_deaccessioned', $vb_is_deaccessioned = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}is_deaccessioned", pInteger)); $this->set('deaccession_notes', $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}deaccession_notes", pString)); $this->set('deaccession_type_id', $x = $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}deaccession_type_id", pString)); $this->set('deaccession_date', $po_request->getParameter("{$vs_placement_code}{$vs_form_prefix}deaccession_date", pString)); if ($vb_is_deaccessioned && (bool) $this->getAppConfig()->get('deaccession_force_access_private')) { $this->get('access', 0); } // set access to private for accessioned items $this->update(); break; # ------------------------------- // This bundle is only available for objects # ------------------------------- // This bundle is only available for objects case 'ca_object_checkouts': // object checkout information if ($vb_batch) { return null; } // not supported in batch mode if (!$vb_batch && !$this->getPrimaryKey()) { return null; } // not supported for new records if (!$po_request->user->canDoAction('can_edit_ca_objects')) { break; } // NOOP (for now) break; # ------------------------------- } } } BaseModel::unsetChangeLogUnitID(); $va_bundle_names = array(); foreach ($va_bundles as $va_bundle) { $vs_bundle_name = str_replace('ca_attribute_', '', $va_bundle['bundle_name']); if (!$this->getAppDatamodel()->getInstanceByTableName($vs_bundle_name, true)) { $vs_bundle_name = $this->tableName() . '.' . $vs_bundle_name; } $va_bundle_names[] = $vs_bundle_name; } // validate metadata dictionary rules $va_violations = $this->validateUsingMetadataDictionaryRules(array('bundles' => $va_bundle_names)); if (sizeof($va_violations)) { if ($vb_we_set_transaction && isset($va_violations['ERR']) && is_array($va_violations['ERR']) && sizeof($va_violations['ERR']) > 0) { BaseModel::unsetChangeLogUnitID(); $this->removeTransaction(false); $this->_FIELD_VALUES[$this->primaryKey()] = null; // clear primary key since transaction has been rolled back foreach ($va_violations['ERR'] as $vs_bundle => $va_errs_by_bundle) { foreach ($va_errs_by_bundle as $vn_i => $va_rule) { $vs_bundle = str_replace($this->tableName() . ".", "", $vs_bundle); $po_request->addActionErrors(array(new Error(1100, $va_rule['rule_settings']['violationMessage'], "BundlableLabelableBaseModelWithAttributes->saveBundlesForScreen()", 'MetadataDictionary', false, false)), $vs_bundle, 'general'); } } return false; } } // prepopulate fields $vs_prepopulate_cfg = $this->getAppConfig()->get('prepopulate_config'); $o_prepopulate_conf = Configuration::load($vs_prepopulate_cfg); if ($o_prepopulate_conf->get('prepopulate_fields_on_save')) { $this->prepopulateFields(array('prepopulateConfig' => $vs_prepopulate_cfg)); } if ($vb_dryrun) { $this->removeTransaction(false); } if ($vb_we_set_transaction) { $this->removeTransaction(true); } return true; }
public function AjaxAddItem() { if (!$this->request->isLoggedIn()) { $this->response->setRedirect(caNavUrl($this->request, '', 'LoginReg', 'loginForm')); return; } global $g_ui_locale_id; // current locale_id for user $va_errors = array(); $o_purifier = new HTMLPurifier(); # --- set_id is passed through form, otherwise we're saving a new set, and adding the item to it if ($this->request->getParameter('set_id', pInteger)) { $t_set = $this->_getSet(__CA_EDIT_READ_ACCESS__); if (!$t_set && ($t_set = $this->_getSet(__CA_SET_READ_ACCESS__))) { $va_errors["general"] = _t("You can not add items to this lightbox. You have read only access."); $this->view->setVar('errors', $va_errors); $this->addItemForm(); return; } } else { $t_set = new ca_sets(); # --- set name - if not sent, make a decent default $ps_name = $o_purifier->purify($this->request->getParameter('name', pString)); if (!$ps_name) { $ps_name = _t("Your lightbox"); } # --- set description - optional $ps_description = $o_purifier->purify($this->request->getParameter('description', pString)); $t_list = new ca_lists(); $vn_set_type_user = $t_list->getItemIDFromList('set_types', $this->request->config->get('user_set_type')); $t_object = new ca_objects(); $vn_object_table_num = $t_object->tableNum(); $t_set->setMode(ACCESS_WRITE); $t_set->set('access', 1); #$t_set->set('access', $this->request->getParameter('access', pInteger)); $t_set->set('table_num', $vn_object_table_num); $t_set->set('type_id', $vn_set_type_user); $t_set->set('user_id', $this->request->getUserID()); $t_set->set('set_code', $this->request->getUserID() . '_' . time()); # --- create new attribute if ($ps_description) { $t_set->addAttribute(array('description' => $ps_description, 'locale_id' => $g_ui_locale_id), 'description'); } $t_set->insert(); if ($t_set->numErrors()) { $va_errors["general"] = join("; ", $t_set->getErrors()); $this->view->setVar('errors', $va_errors); $this->addItemForm(); return; } else { # --- save name - add new label $t_set->addLabel(array('name' => $ps_name), $g_ui_locale_id, null, true); # --- select the current set $this->request->user->setVar('current_set_id', $t_set->get("set_id")); } } if ($t_set) { $pn_item_id = null; $pn_object_id = $this->request->getParameter('object_id', pInteger); if ($pn_object_id) { if (!$t_set->isInSet("ca_objects", $pn_object_id, $t_set->get("set_id"))) { if ($pn_item_id = $t_set->addItem($pn_object_id, array(), $this->request->getUserID())) { // // Select primary representation // $t_object = new ca_objects($pn_object_id); $vn_rep_id = $t_object->getPrimaryRepresentationID(); // get representation_id for primary $t_item = new ca_set_items($pn_item_id); $t_item->addSelectedRepresentation($vn_rep_id); // flag as selected in item vars $t_item->update(); $va_errors = array(); $this->view->setVar('message', _t("Successfully added item.")); $this->render("Form/reload_html.php"); } else { $va_errors["message"] = _t('Could not add item to lightbox'); $this->render("Form/reload_html.php"); } } else { $this->view->setVar('message', _t("Item already in lightbox.")); $this->render("Form/reload_html.php"); } } else { $this->view->setVar('message', _t("Object ID is not defined")); $this->render("Form/reload_html.php"); } } }
public function shareSet() { $pn_set_id = $this->request->getParameter('set_id', pInteger); $t_set = new ca_sets(); if (!$t_set->haveAccessToSet($this->request->getUserID(), __CA_SET_EDIT_ACCESS__, $pn_set_id)) { $this->notification->addNotification(_t("You cannot share this set"), "message"); } else { $t_set->load($pn_set_id); $vs_form_prefix = 'shareSetForm_'; $va_users_to_set = array(); foreach ($_REQUEST as $vs_key => $vs_val) { if (preg_match("!^{$vs_form_prefix}id(.*)\$!", $vs_key, $va_matches)) { $vn_user_id = (int) $this->request->getParameter($vs_form_prefix . 'id' . $va_matches[1], pInteger); $vn_access = $this->request->getParameter($vs_form_prefix . 'access_' . $va_matches[1], pInteger); if ($vn_access > 0) { $va_users_to_set[$vn_user_id] = $vn_access; } } } $t_set->setUsers($va_users_to_set); if ($t_set->numErrors()) { $this->notification->addNotification(_t("There were errors while sharing: %1", join("; ", $t_set->getErrors())), "message"); } else { $vn_c = sizeof($va_users_to_set); $this->notification->addNotification($vn_c == 1 ? _t("Shared set with %1 user", $vn_c) : _t("Shared set with %1 users", $vn_c), "message"); } } $this->index(); }
/** * @param RequestHTTP $po_request * @param null|array $pa_options * progressCallback = * reportCallback = * sendMail = * log = log directory path * logLevel = KLogger constant for minimum log level to record. Default is KLogger::INFO. Constants are, in descending order of shrillness: * KLogger::EMERG = Emergency messages (system is unusable) * KLogger::ALERT = Alert messages (action must be taken immediately) * KLogger::CRIT = Critical conditions * KLogger::ERR = Error conditions * KLogger::WARN = Warnings * KLogger::NOTICE = Notices (normal but significant conditions) * KLogger::INFO = Informational messages * KLogger::DEBUG = Debugging messages * @return array */ public static function importMediaFromDirectory($po_request, $pa_options = null) { global $g_ui_locale_id; $vs_log_dir = caGetOption('log', $pa_options, __CA_APP_DIR__ . "/log"); $vs_log_level = caGetOption('logLevel', $pa_options, "INFO"); if (!is_writeable($vs_log_dir)) { $vs_log_dir = caGetTempDirPath(); } $vn_log_level = BatchProcessor::_logLevelStringToNumber($vs_log_level); $o_log = new KLogger($vs_log_dir, $vn_log_level); $vs_import_target = caGetOption('importTarget', $pa_options, 'ca_objects'); $t_instance = $po_request->getAppDatamodel()->getInstance($vs_import_target); $o_eventlog = new Eventlog(); $t_set = new ca_sets(); $va_notices = $va_errors = array(); $vb_we_set_transaction = false; $o_trans = isset($pa_options['transaction']) && $pa_options['transaction'] ? $pa_options['transaction'] : null; if (!$o_trans) { $vb_we_set_transaction = true; $o_trans = new Transaction($t_set->getDb()); } $o_batch_log = new Batchlog(array('user_id' => $po_request->getUserID(), 'batch_type' => 'MI', 'table_num' => (int) $t_instance->tableNum(), 'notes' => '', 'transaction' => $o_trans)); if (!is_dir($pa_options['importFromDirectory'])) { $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => $vs_msg = _t("Specified import directory '%1' is invalid", $pa_options['importFromDirectory']))); $o_log->logError($vs_msg); return null; } $vs_batch_media_import_root_directory = $po_request->config->get('batch_media_import_root_directory'); if (!preg_match("!^{$vs_batch_media_import_root_directory}!", $pa_options['importFromDirectory'])) { $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => $vs_msg = _t("Specified import directory '%1' is invalid", $pa_options['importFromDirectory']))); $o_log->logError($vs_msg); return null; } if (preg_match("!\\.\\./!", $pa_options['importFromDirectory'])) { $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => $vs_msg = _t("Specified import directory '%1' is invalid", $pa_options['importFromDirectory']))); $o_log->logError($vs_msg); return null; } $vb_include_subdirectories = (bool) $pa_options['includeSubDirectories']; $vb_delete_media_on_import = (bool) $pa_options['deleteMediaOnImport']; $vs_import_mode = $pa_options['importMode']; $vs_match_mode = $pa_options['matchMode']; $vn_type_id = $pa_options[$vs_import_target . '_type_id']; $vn_rep_type_id = $pa_options['ca_object_representations_type_id']; $va_limit_matching_to_type_ids = $pa_options[$vs_import_target . '_limit_matching_to_type_ids']; $vn_access = $pa_options[$vs_import_target . '_access']; $vn_object_representation_access = $pa_options['ca_object_representations_access']; $vn_status = $pa_options[$vs_import_target . '_status']; $vn_object_representation_status = $pa_options['ca_object_representations_status']; $vn_rel_type_id = isset($pa_options[$vs_import_target . '_representation_relationship_type']) ? $pa_options[$vs_import_target . '_representation_relationship_type'] : null; $vn_mapping_id = $pa_options[$vs_import_target . '_mapping_id']; $vn_object_representation_mapping_id = $pa_options['ca_object_representations_mapping_id']; $vs_idno_mode = $pa_options['idnoMode']; $vs_idno = $pa_options['idno']; $vs_representation_idno_mode = $pa_options['representationIdnoMode']; $vs_representation_idno = $pa_options['representation_idno']; $vs_set_mode = $pa_options['setMode']; $vs_set_create_name = $pa_options['setCreateName']; $vn_set_id = $pa_options['set_id']; $vn_locale_id = $pa_options['locale_id']; $vs_skip_file_list = $pa_options['skipFileList']; $vs_skip_file_list = $pa_options['skipFileList']; $vb_allow_duplicate_media = $pa_options['allowDuplicateMedia']; $va_relationship_type_id_for = array(); if (is_array($va_create_relationship_for = $pa_options['create_relationship_for'])) { foreach ($va_create_relationship_for as $vs_rel_table) { $va_relationship_type_id_for[$vs_rel_table] = $pa_options['relationship_type_id_for_' . $vs_rel_table]; } } if (!$vn_locale_id) { $vn_locale_id = $g_ui_locale_id; } $va_files_to_process = caGetDirectoryContentsAsList($pa_options['importFromDirectory'], $vb_include_subdirectories); $o_log->logInfo(_t('Found %1 files in directory \'%2\'', sizeof($va_files_to_process), $pa_options['importFromDirectory'])); if ($vs_set_mode == 'add') { $t_set->load($vn_set_id); } else { if ($vs_set_mode == 'create' && $vs_set_create_name) { $va_set_ids = $t_set->getSets(array('user_id' => $po_request->getUserID(), 'table' => $t_instance->tableName(), 'access' => __CA_SET_EDIT_ACCESS__, 'setIDsOnly' => true, 'name' => $vs_set_create_name)); $vn_set_id = null; if (is_array($va_set_ids) && sizeof($va_set_ids) > 0) { $vn_possible_set_id = array_shift($va_set_ids); if ($t_set->load($vn_possible_set_id)) { $vn_set_id = $t_set->getPrimaryKey(); } } else { $vs_set_code = mb_substr(preg_replace("![^A-Za-z0-9_\\-]+!", "_", $vs_set_create_name), 0, 100); if ($t_set->load(array('set_code' => $vs_set_code))) { $vn_set_id = $t_set->getPrimaryKey(); } } if (!$t_set->getPrimaryKey()) { $t_set->setMode(ACCESS_WRITE); $t_set->set('user_id', $po_request->getUserID()); $t_set->set('type_id', $po_request->config->get('ca_sets_default_type')); $t_set->set('table_num', $t_instance->tableNum()); $t_set->set('set_code', $vs_set_code); $t_set->insert(); if ($t_set->numErrors()) { $va_notices['create_set'] = array('idno' => '', 'label' => _t('Create set %1', $vs_set_create_name), 'message' => $vs_msg = _t('Failed to create set %1: %2', $vs_set_create_name, join("; ", $t_set->getErrors())), 'status' => 'SET ERROR'); $o_log->logError($vs_msg); } else { $t_set->addLabel(array('name' => $vs_set_create_name), $vn_locale_id, null, true); if ($t_set->numErrors()) { $va_notices['add_set_label'] = array('idno' => '', 'label' => _t('Add label to set %1', $vs_set_create_name), 'message' => $vs_msg = _t('Failed to add label to set: %1', join("; ", $t_set->getErrors())), 'status' => 'SET ERROR'); $o_log->logError($vs_msg); } $vn_set_id = $t_set->getPrimaryKey(); } } } else { $vn_set_id = null; // no set } } if ($t_set->getPrimaryKey() && !$t_set->haveAccessToSet($po_request->getUserID(), __CA_SET_EDIT_ACCESS__)) { $va_notices['set_access'] = array('idno' => '', 'label' => _t('You do not have access to set %1', $vs_set_create_name), 'message' => $vs_msg = _t('Cannot add to set %1 because you do not have edit access', $vs_set_create_name), 'status' => 'SET ERROR'); $o_log->logError($vs_msg); $vn_set_id = null; $t_set = new ca_sets(); } $vn_num_items = sizeof($va_files_to_process); // Get list of regex packages that user can use to extract object idno's from filenames $va_regex_list = caBatchGetMediaFilenameToIdnoRegexList(array('log' => $o_log)); // Get list of replacements that user can use to transform file names to match object idnos $va_replacements_list = caBatchGetMediaFilenameReplacementRegexList(array('log' => $o_log)); // Get list of files (or file name patterns) to skip $va_skip_list = preg_split("![\r\n]+!", $vs_skip_file_list); foreach ($va_skip_list as $vn_i => $vs_skip) { if (!strlen($va_skip_list[$vn_i] = trim($vs_skip))) { unset($va_skip_list[$vn_i]); } } $vn_c = 0; $vn_start_time = time(); $va_report = array(); foreach ($va_files_to_process as $vs_file) { $va_tmp = explode("/", $vs_file); $f = array_pop($va_tmp); $d = array_pop($va_tmp); array_push($va_tmp, $d); $vs_directory = join("/", $va_tmp); // Skip file names using $vs_skip_file_list if (BatchProcessor::_skipFile($f, $va_skip_list)) { $o_log->logInfo(_t('Skipped file %1 because it was on the skipped files list', $f)); continue; } $vs_relative_directory = preg_replace("!{$vs_batch_media_import_root_directory}[/]*!", "", $vs_directory); // does representation already exist? if (!$vb_allow_duplicate_media && ($t_dupe = ca_object_representations::mediaExists($vs_file))) { $va_notices[$vs_relative_directory . '/' . $f] = array('idno' => '', 'label' => $f, 'message' => $vs_msg = _t('Skipped %1 from %2 because it already exists %3', $f, $vs_relative_directory, caEditorLink($po_request, _t('(view)'), 'button', 'ca_object_representations', $t_dupe->getPrimaryKey())), 'status' => 'SKIPPED'); $o_log->logInfo($vs_msg); continue; } $t_instance = $po_request->getAppDatamodel()->getInstance($vs_import_target, false); $t_instance->setTransaction($o_trans); $vs_modified_filename = $f; $va_extracted_idnos_from_filename = array(); if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'ALWAYS_MATCH')) || is_array($va_create_relationship_for) && sizeof($va_create_relationship_for)) { foreach ($va_regex_list as $vs_regex_name => $va_regex_info) { $o_log->logDebug(_t("Processing mediaFilenameToObjectIdnoRegexes entry %1", $vs_regex_name)); foreach ($va_regex_info['regexes'] as $vs_regex) { switch ($vs_match_mode) { case 'DIRECTORY_NAME': $va_names_to_match = array($d); $o_log->logDebug(_t("Trying to match on directory '%1'", $d)); break; case 'FILE_AND_DIRECTORY_NAMES': $va_names_to_match = array($f, $d); $o_log->logDebug(_t("Trying to match on directory '%1' and file name '%2'", $d, $f)); break; default: case 'FILE_NAME': $va_names_to_match = array($f); $o_log->logDebug(_t("Trying to match on file name '%1'", $f)); break; } // are there any replacements? if so, try to match each element in $va_names_to_match AND all results of the replacements if (is_array($va_replacements_list) && sizeof($va_replacements_list) > 0) { $va_names_to_match_copy = $va_names_to_match; foreach ($va_names_to_match_copy as $vs_name) { foreach ($va_replacements_list as $vs_replacement_code => $va_replacement) { if (isset($va_replacement['search']) && is_array($va_replacement['search'])) { $va_replace = caGetOption('replace', $va_replacement); $va_search = array(); foreach ($va_replacement['search'] as $vs_search) { $va_search[] = '!' . $vs_search . '!'; } $vs_replacement_result = @preg_replace($va_search, $va_replace, $vs_name); if (is_null($vs_replacement_result)) { $o_log->logError(_t("There was an error in preg_replace while processing replacement %1.", $vs_replacement_code)); } if ($vs_replacement_result && strlen($vs_replacement_result) > 0) { $o_log->logDebug(_t("The result for replacement with code %1 applied to value '%2' is '%3' and was added to the list of file names used for matching.", $vs_replacement_code, $vs_name, $vs_replacement_result)); $va_names_to_match[] = $vs_replacement_result; } } else { $o_log->logDebug(_t("Skipped replacement %1 because no search expression was defined.", $vs_replacement_code)); } } } } $o_log->logDebug("Names to match: " . print_r($va_names_to_match, true)); foreach ($va_names_to_match as $vs_match_name) { if (preg_match('!' . $vs_regex . '!', $vs_match_name, $va_matches)) { $o_log->logDebug(_t("Matched name %1 on regex %2", $vs_match_name, $vs_regex)); if (!$vs_idno || strlen($va_matches[1]) < strlen($vs_idno)) { $vs_idno = $va_matches[1]; } if (!$vs_modified_filename || strlen($vs_modified_filename) > strlen($va_matches[1])) { $vs_modified_filename = $va_matches[1]; } $va_extracted_idnos_from_filename[] = $va_matches[1]; if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'ALWAYS_MATCH'))) { if (!is_array($va_fields_to_match_on = $po_request->config->getList('batch_media_import_match_on')) || !sizeof($va_fields_to_match_on)) { $batch_media_import_match_on = array('idno'); } $vs_bool = 'OR'; $va_values = array(); foreach ($va_fields_to_match_on as $vs_fld) { if (in_array($vs_fld, array('preferred_labels', 'nonpreferred_labels'))) { $va_values[$vs_fld] = array($vs_fld => array('name' => $va_matches[1])); } else { $va_values[$vs_fld] = $va_matches[1]; } } if (is_array($va_limit_matching_to_type_ids) && sizeof($va_limit_matching_to_type_ids) > 0) { $va_values['type_id'] = $va_limit_matching_to_type_ids; $vs_bool = 'AND'; } $o_log->logDebug("Trying to find records using boolean {$vs_bool} and values " . print_r($va_values, true)); if (class_exists($vs_import_target) && ($vn_id = $vs_import_target::find($va_values, array('returnAs' => 'firstId', 'boolean' => $vs_bool)))) { if ($t_instance->load($vn_id)) { $va_notices[$vs_relative_directory . '/' . $vs_match_name . '_match'] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'message' => $vs_msg = _t('Matched media %1 from %2 to %3 using expression "%4"', $f, $vs_relative_directory, caGetTableDisplayName($vs_import_target, false), $va_regex_info['displayName']), 'status' => 'MATCHED'); $o_log->logInfo($vs_msg); } break 3; } } } else { $o_log->logDebug(_t("Couldn't match name %1 on regex %2", $vs_match_name, $vs_regex)); } } } } } if (!$t_instance->getPrimaryKey()) { // Use filename as idno if all else fails if ($t_instance->load(array('idno' => $f, 'deleted' => 0))) { $va_notices[$vs_relative_directory . '/' . $f . '_match'] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'message' => $vs_msg = _t('Matched media %1 from %2 to %3 using filename', $f, $vs_relative_directory, caGetTableDisplayName($vs_import_target, false)), 'status' => 'MATCHED'); $o_log->logInfo($vs_msg); } } switch ($vs_representation_idno_mode) { case 'filename': // use the filename as identifier $vs_rep_idno = $f; break; case 'filename_no_ext': // use filename without extension as identifier $vs_rep_idno = preg_replace('/\\.[^.\\s]{3,4}$/', '', $f); break; case 'directory_and_filename': // use the directory + filename as identifier $vs_rep_idno = $d . '/' . $f; break; default: // use idno from form $vs_rep_idno = $vs_representation_idno; break; } $t_new_rep = null; if ($t_instance->getPrimaryKey() && $t_instance instanceof RepresentableBaseModel) { // found existing object $t_instance->setMode(ACCESS_WRITE); $t_new_rep = $t_instance->addRepresentation($vs_directory . '/' . $f, $vn_rep_type_id, $vn_locale_id, $vn_object_representation_status, $vn_object_representation_access, false, array('idno' => $vs_rep_idno), array('original_filename' => $f, 'returnRepresentation' => true, 'type_id' => $vn_rel_type_id)); if ($t_instance->numErrors()) { $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => _t("Error importing {$f} from {$vs_directory}: %1", join('; ', $t_instance->getErrors())))); $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'errors' => $t_instance->errors(), 'message' => $vs_msg = _t("Error importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors())), 'status' => 'ERROR'); $o_log->logError($vs_msg); $o_trans->rollback(); continue; } else { if ($vb_delete_media_on_import) { @unlink($vs_directory . '/' . $f); } } } else { // should we create new record? if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'DONT_MATCH'))) { $t_instance->setMode(ACCESS_WRITE); $t_instance->set('type_id', $vn_type_id); $t_instance->set('locale_id', $vn_locale_id); $t_instance->set('status', $vn_status); $t_instance->set('access', $vn_access); // for places, take first hierarchy we can find. in most setups there is but one. we might wanna make this configurable via setup screen at some point if ($t_instance->hasField('hierarchy_id')) { $va_hierarchies = $t_instance->getHierarchyList(); reset($va_hierarchies); $vn_hierarchy_id = key($va_hierarchies); $t_instance->set('hierarchy_id', $vn_hierarchy_id); } switch ($vs_idno_mode) { case 'filename': // use the filename as identifier $t_instance->set('idno', $f); break; case 'filename_no_ext': // use filename without extension as identifier $f_no_ext = preg_replace('/\\.[^.\\s]{3,4}$/', '', $f); $t_instance->set('idno', $f_no_ext); break; case 'directory_and_filename': // use the directory + filename as identifier $t_instance->set('idno', $d . '/' . $f); break; default: // Calculate identifier using numbering plugin $o_numbering_plugin = $t_instance->getIDNoPlugInInstance(); if (!($vs_sep = $o_numbering_plugin->getSeparator())) { $vs_sep = ''; } if (!is_array($va_idno_values = $o_numbering_plugin->htmlFormValuesAsArray('idno', null, false, false, true))) { $va_idno_values = array(); } $t_instance->set('idno', join($vs_sep, $va_idno_values)); // true=always set serial values, even if they already have a value; this let's us use the original pattern while replacing the serial value every time through break; } $t_instance->insert(); if ($t_instance->numErrors()) { $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => _t("Error creating new record while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors())))); $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'errors' => $t_instance->errors(), 'message' => $vs_msg = _t("Error creating new record while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors())), 'status' => 'ERROR'); $o_log->logError($vs_msg); $o_trans->rollback(); continue; } if ($t_instance->tableName() == 'ca_entities') { // entity labels deserve special treatment $t_instance->addLabel(array('surname' => $f), $vn_locale_id, null, true); } else { $t_instance->addLabel(array($t_instance->getLabelDisplayField() => $f), $vn_locale_id, null, true); } if ($t_instance->numErrors()) { $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => _t("Error creating record label while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors())))); $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'errors' => $t_instance->errors(), 'message' => $vs_msg = _t("Error creating record label while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors())), 'status' => 'ERROR'); $o_log->logError($vs_msg); $o_trans->rollback(); continue; } $t_new_rep = $t_instance->addRepresentation($vs_directory . '/' . $f, $vn_rep_type_id, $vn_locale_id, $vn_object_representation_status, $vn_object_representation_access, true, array('idno' => $vs_rep_idno), array('original_filename' => $f, 'returnRepresentation' => true, 'type_id' => $vn_rel_type_id)); if ($t_instance->numErrors()) { $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => _t("Error importing %1 from %2: ", $f, $vs_relative_directory, join('; ', $t_instance->getErrors())))); $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'errors' => $t_instance->errors(), 'message' => $vs_msg = _t("Error importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_instance->getErrors())), 'status' => 'ERROR'); $o_log->logError($vs_msg); $o_trans->rollback(); continue; } else { if ($vb_delete_media_on_import) { @unlink($vs_directory . '/' . $f); } } } } if ($t_instance->getPrimaryKey()) { // Perform import of embedded metadata (if required) if ($vn_mapping_id) { ca_data_importers::importDataFromSource($vs_directory . '/' . $f, $vn_mapping_id, array('logLevel' => $vs_log_level, 'format' => 'exif', 'forceImportForPrimaryKeys' => array($t_instance->getPrimaryKey(), 'transaction' => $o_trans))); } if ($vn_object_representation_mapping_id) { ca_data_importers::importDataFromSource($vs_directory . '/' . $f, $vn_object_representation_mapping_id, array('logLevel' => $vs_log_level, 'format' => 'exif', 'forceImportForPrimaryKeys' => array($t_new_rep->getPrimaryKey()), 'transaction' => $o_trans)); } $va_notices[$t_instance->getPrimaryKey()] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_instance->getLabelForDisplay(), 'message' => $vs_msg = _t('Imported %1 as %2', $f, $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD'))), 'status' => 'SUCCESS'); $o_log->logInfo($vs_msg); if ($vn_set_id) { $t_set->addItem($t_instance->getPrimaryKey(), null, $po_request->getUserID()); } $o_batch_log->addItem($t_instance->getPrimaryKey(), $t_instance->errors()); // Create relationships? if (is_array($va_create_relationship_for) && sizeof($va_create_relationship_for) && is_array($va_extracted_idnos_from_filename) && sizeof($va_extracted_idnos_from_filename)) { foreach ($va_extracted_idnos_from_filename as $vs_idno) { foreach ($va_create_relationship_for as $vs_rel_table) { if (!isset($va_relationship_type_id_for[$vs_rel_table]) || !$va_relationship_type_id_for[$vs_rel_table]) { continue; } $t_rel = $t_instance->getAppDatamodel()->getInstanceByTableName($vs_rel_table); if ($t_rel->load(array($t_rel->getProperty('ID_NUMBERING_ID_FIELD') => $vs_idno))) { $t_instance->addRelationship($vs_rel_table, $t_rel->getPrimaryKey(), $va_relationship_type_id_for[$vs_rel_table]); if (!$t_instance->numErrors()) { $va_notices[$t_instance->getPrimaryKey() . '_rel'] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $vs_label = $t_instance->getLabelForDisplay(), 'message' => $vs_msg = _t('Added relationship between <em>%1</em> and %2 <em>%3</em>', $vs_label, $t_rel->getProperty('NAME_SINGULAR'), $t_rel->getLabelForDisplay()), 'status' => 'RELATED'); $o_log->logInfo($vs_msg); } else { $va_notices[$t_instance->getPrimaryKey()] = array('idno' => $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $vs_label = $t_instance->getLabelForDisplay(), 'message' => $vs_msg = _t('Could not add relationship between <em>%1</em> and %2 <em>%3</em>: %4', $vs_label, $t_rel->getProperty('NAME_SINGULAR'), $t_rel->getLabelForDisplay(), join("; ", $t_instance->getErrors())), 'status' => 'ERROR'); $o_log->logError($vs_msg); } } } } } } else { $va_notices[$vs_relative_directory . '/' . $f] = array('idno' => '', 'label' => $f, 'message' => $vs_msg = $vs_import_mode == 'ALWAYS_MATCH' ? _t('Skipped %1 from %2 because it could not be matched', $f, $vs_relative_directory) : _t('Skipped %1 from %2', $f, $vs_relative_directory), 'status' => 'SKIPPED'); $o_log->logInfo($vs_msg); } if (isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) { $ps_callback($po_request, $vn_c, $vn_num_items, _t("[%3/%4] Processing %1 (%3)", caTruncateStringWithEllipsis($vs_relative_directory, 20) . '/' . caTruncateStringWithEllipsis($f, 30), $t_instance->get($t_instance->getProperty('ID_NUMBERING_ID_FIELD')), $vn_c, $vn_num_items), $t_new_rep, time() - $vn_start_time, memory_get_usage(true), $vn_c, sizeof($va_errors)); } $vn_c++; } if (isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) { $ps_callback($po_request, $vn_num_items, $vn_num_items, _t("Processing completed"), null, time() - $vn_start_time, memory_get_usage(true), $vn_c, sizeof($va_errors)); } $vn_elapsed_time = time() - $vn_start_time; if (isset($pa_options['reportCallback']) && ($ps_callback = $pa_options['reportCallback'])) { $va_general = array('elapsedTime' => $vn_elapsed_time, 'numErrors' => sizeof($va_errors), 'numProcessed' => $vn_c, 'batchSize' => $vn_num_items, 'table' => $t_instance->tableName(), 'set_id' => $t_set->getPrimaryKey(), 'setName' => $t_set->getLabelForDisplay()); $ps_callback($po_request, $va_general, $va_notices, $va_errors); } $o_batch_log->close(); if ($vb_we_set_transaction) { if (sizeof($va_errors) > 0) { $o_trans->rollback(); } else { $o_trans->commit(); } } $vs_set_name = $t_set->getLabelForDisplay(); $vs_started_on = caGetLocalizedDate($vn_start_time); if (isset($pa_options['sendMail']) && $pa_options['sendMail']) { if ($vs_email = trim($po_request->user->get('email'))) { caSendMessageUsingView($po_request, array($vs_email => $po_request->user->get('fname') . ' ' . $po_request->user->get('lname')), __CA_ADMIN_EMAIL__, _t('[%1] Batch media import completed', $po_request->config->get('app_display_name')), 'batch_media_import_completed.tpl', array('notices' => $va_notices, 'errors' => $va_errors, 'directory' => $vs_relative_directory, 'numErrors' => sizeof($va_errors), 'numProcessed' => $vn_c, 'subjectNameSingular' => _t('file'), 'subjectNamePlural' => _t('files'), 'startedOn' => $vs_started_on, 'completedOn' => caGetLocalizedDate(time()), 'setName' => $vn_set_id ? $vs_set_name : null, 'elapsedTime' => caFormatInterval($vn_elapsed_time))); } } if (isset($pa_options['sendSMS']) && $pa_options['sendSMS']) { SMS::send($po_request->getUserID(), _t("[%1] Media import processing for directory %2 with %3 %4 begun at %5 is complete", $po_request->config->get('app_display_name'), $vs_relative_directory, $vn_num_items, $vn_num_items == 1 ? _t('file') : _t('files'), $vs_started_on)); } $o_log->logInfo(_t("Media import processing for directory %1 with %2 %3 begun at %4 is complete", $vs_relative_directory, $vn_num_items, $vn_num_items == 1 ? _t('file') : _t('files'))); return array('errors' => $va_errors, 'notices' => $va_notices, 'processing_time' => caFormatInterval($vn_elapsed_time)); }
/** * @param array $pa_options * progressCallback = * reportCallback = * sendMail = */ public static function importMediaFromDirectory($po_request, $pa_options = null) { global $g_ui_locale_id; $t_object = new ca_objects(); $o_eventlog = new Eventlog(); $t_set = new ca_sets(); $va_notices = $va_errors = array(); $vb_we_set_transaction = false; $o_trans = isset($pa_options['transaction']) && $pa_options['transaction'] ? $pa_options['transaction'] : null; if (!$o_trans) { $vb_we_set_transaction = true; $o_trans = new Transaction(); } $o_log = new Batchlog(array('user_id' => $po_request->getUserID(), 'batch_type' => 'MI', 'table_num' => (int) $t_object->tableNum(), 'notes' => '', 'transaction' => $o_trans)); if (!is_dir($pa_options['importFromDirectory'])) { $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Specified import directory is invalid")); return null; } $vs_batch_media_import_root_directory = $po_request->config->get('batch_media_import_root_directory'); if (!preg_match("!^{$vs_batch_media_import_root_directory}!", $pa_options['importFromDirectory'])) { $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Specified import directory is invalid")); return null; } if (preg_match("!/\\.\\.!", $vs_directory) || preg_match("!\\.\\./!", $pa_options['importFromDirectory'])) { $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Specified import directory is invalid")); return null; } $vb_include_subdirectories = (bool) $pa_options['includeSubDirectories']; $vb_delete_media_on_import = (bool) $pa_options['deleteMediaOnImport']; $vs_import_mode = $pa_options['importMode']; $vs_match_mode = $pa_options['matchMode']; $vn_object_type_id = $pa_options['ca_objects_type_id']; $vn_rep_type_id = $pa_options['ca_object_representations_type_id']; $vn_object_access = $pa_options['ca_objects_access']; $vn_object_representation_access = $pa_options['ca_object_representations_access']; $vn_object_status = $pa_options['ca_objects_status']; $vn_object_representation_status = $pa_options['ca_object_representations_status']; $vs_idno_mode = $pa_options['idnoMode']; $vs_idno = $pa_options['idno']; $vs_set_mode = $pa_options['setMode']; $vs_set_create_name = $pa_options['setCreateName']; $vn_set_id = $pa_options['set_id']; $vn_locale_id = $pa_options['locale_id']; $vs_skip_file_list = $pa_options['skipFileList']; $va_relationship_type_id_for = array(); if (is_array($va_create_relationship_for = $pa_options['create_relationship_for'])) { foreach ($va_create_relationship_for as $vs_rel_table) { $va_relationship_type_id_for[$vs_rel_table] = $pa_options['relationship_type_id_for_' . $vs_rel_table]; } } if (!$vn_locale_id) { $vn_locale_id = $g_ui_locale_id; } $va_files_to_process = caGetDirectoryContentsAsList($pa_options['importFromDirectory'], $vb_include_subdirectories); if ($vs_set_mode == 'add') { $t_set->load($vn_set_id); } else { if ($vs_set_mode == 'create' && $vs_set_create_name) { $va_set_ids = $t_set->getSets(array('user_id' => $po_request->getUserID(), 'table' => 'ca_objects', 'access' => __CA_SET_EDIT_ACCESS__, 'setIDsOnly' => true, 'name' => $vs_set_create_name)); $vn_set_id = null; if (is_array($va_set_ids) && sizeof($va_set_ids) > 0) { $vn_possible_set_id = array_shift($va_set_ids); if ($t_set->load($vn_possible_set_id)) { $vn_set_id = $t_set->getPrimaryKey(); } } else { $vs_set_code = mb_substr(preg_replace("![^A-Za-z0-9_\\-]+!", "_", $vs_set_create_name), 0, 100); if ($t_set->load(array('set_code' => $vs_set_code))) { $vn_set_id = $t_set->getPrimaryKey(); } } if (!$t_set->getPrimaryKey()) { $t_set->setMode(ACCESS_WRITE); $t_set->set('user_id', $po_request->getUserID()); $t_set->set('type_id', $po_request->config->get('ca_sets_default_type')); $t_set->set('table_num', $t_object->tableNum()); $t_set->set('set_code', $vs_set_code); $t_set->insert(); if ($t_set->numErrors()) { $va_notices['create_set'] = array('idno' => '', 'label' => _t('Create set %1', $vs_set_create_name), 'message' => _t('Failed to create set %1: %2', $vs_set_create_name, join("; ", $t_set->getErrors())), 'status' => 'SET ERROR'); } else { $t_set->addLabel(array('name' => $vs_set_create_name), $vn_locale_id, null, true); if ($t_set->numErrors()) { $va_notices['add_set_label'] = array('idno' => '', 'label' => _t('Add label to set %1', $vs_set_create_name), 'message' => _t('Failed to add label to set: %1', join("; ", $t_set->getErrors())), 'status' => 'SET ERROR'); } $vn_set_id = $t_set->getPrimaryKey(); } } } else { $vn_set_id = null; // no set } } if ($t_set->getPrimaryKey() && !$t_set->haveAccessToSet($po_request->getUserID(), __CA_SET_EDIT_ACCESS__)) { $va_notices['set_access'] = array('idno' => '', 'label' => _t('You do not have access to set %1', $vs_set_create_name), 'message' => _t('Cannot add to set %1 because you do not have edit access', $vs_set_create_name), 'status' => 'SET ERROR'); $vn_set_id = null; $t_set = new ca_sets(); } $vn_num_items = sizeof($va_files_to_process); // Get list of regex packages that user can use to extract object idno's from filenames $va_regex_list = $po_request->config->getAssoc('mediaFilenameToObjectIdnoRegexes'); if (!is_array($va_regex_list)) { $va_regex_list = array(); } // Get list of files (or file name patterns) to skip $va_skip_list = preg_split("![\r\n]+!", $vs_skip_file_list); foreach ($va_skip_list as $vn_i => $vs_skip) { if (!strlen($va_skip_list[$vn_i] = trim($vs_skip))) { unset($va_skip_list[$vn_i]); } } $vn_c = 0; $vn_start_time = time(); $va_report = array(); foreach ($va_files_to_process as $vs_file) { $va_tmp = explode("/", $vs_file); $f = array_pop($va_tmp); $d = array_pop($va_tmp); array_push($va_tmp, $d); $vs_directory = join("/", $va_tmp); // Skip file names using $vs_skip_file_list if (BatchProcessor::_skipFile($f, $va_skip_list)) { continue; } $vs_relative_directory = preg_replace("!{$vs_batch_media_import_root_directory}[/]*!", "", $vs_directory); // does representation already exist? if (ca_object_representations::mediaExists($vs_file)) { $va_notices[$vs_relative_directory . '/' . $f] = array('idno' => '', 'label' => $f, 'message' => _t('Skipped %1 from %2 because it already exists', $f, $vs_relative_directory), 'status' => 'SKIPPED'); continue; } $t_object = new ca_objects(); $t_object->setTransaction($o_trans); $vs_modified_filename = $f; $va_extracted_idnos_from_filename = array(); if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'ALWAYS_MATCH')) || is_array($va_create_relationship_for) && sizeof($va_create_relationship_for)) { foreach ($va_regex_list as $vs_regex_name => $va_regex_info) { foreach ($va_regex_info['regexes'] as $vs_regex) { $va_names_to_match = array(); switch ($vs_match_mode) { case 'DIRECTORY_NAME': $va_names_to_match = array($d); break; case 'FILE_AND_DIRECTORY_NAMES': $va_names_to_match = array($f, $d); break; default: case 'FILE_NAME': $va_names_to_match = array($f); break; } foreach ($va_names_to_match as $vs_match_name) { if (preg_match('!' . $vs_regex . '!', $vs_match_name, $va_matches)) { if (!$vs_idno || strlen($va_matches[1]) < strlen($vs_idno)) { $vs_idno = $va_matches[1]; } if (!$vs_modified_filename || strlen($vs_modified_filename) > strlen($va_matches[1])) { $vs_modified_filename = $va_matches[1]; } $va_extracted_idnos_from_filename[] = $va_matches[1]; if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'ALWAYS_MATCH'))) { if ($t_object->load(array('idno' => $va_matches[1], 'deleted' => 0))) { $va_notices[$vs_relative_directory . '/' . $vs_match_name . '_match'] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'message' => _t('Matched media %1 from %2 to object using %2', $f, $vs_relative_directory, $vs_regex_name), 'status' => 'MATCHED'); break 3; } } } } } } } if (!$t_object->getPrimaryKey()) { // Use filename as idno if all else fails if ($t_object->load(array('idno' => $f, 'deleted' => 0))) { $va_notices[$vs_relative_directory . '/' . $f . '_match'] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'message' => _t('Matched media %1 from %2 to object using filename', $f, $vs_relative_directory), 'status' => 'MATCHED'); } } $t_new_rep = null; if ($t_object->getPrimaryKey()) { // found existing object $t_object->setMode(ACCESS_WRITE); $t_new_rep = $t_object->addRepresentation($vs_directory . '/' . $f, $vn_rep_type_id, $vn_locale_id, $vn_object_representation_status, $vn_object_representation_access, false, array(), array('original_filename' => $f, 'returnRepresentation' => true)); if ($t_object->numErrors()) { $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Error importing {$f} from {$vs_directory}: " . join('; ', $t_object->getErrors()))); $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'errors' => $t_object->errors(), 'message' => _t("Error importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_object->getErrors())), 'status' => 'ERROR'); $o_trans->rollback(); continue; } else { if ($vb_delete_media_on_import) { @unlink($vs_directory . '/' . $f); } } } else { // should we create new object? if (in_array($vs_import_mode, array('TRY_TO_MATCH', 'DONT_MATCH'))) { $t_object->setMode(ACCESS_WRITE); $t_object->set('type_id', $vn_object_type_id); $t_object->set('locale_id', $vn_locale_id); $t_object->set('status', $vn_object_status); $t_object->set('access', $vn_object_access); switch ($vs_idno_mode) { case 'filename': // use the filename as identifier $t_object->set('idno', $f); break; case 'directory_and_filename': // use the directory + filename as identifier $t_object->set('idno', $d . '/' . $f); break; default: // Calculate identifier using numbering plugin $o_numbering_plugin = $t_object->getIDNoPlugInInstance(); if (!($vs_sep = $o_numbering_plugin->getSeparator())) { $vs_sep = ''; } if (!is_array($va_idno_values = $o_numbering_plugin->htmlFormValuesAsArray('idno', $vs_object_idno, false, false, true))) { $va_idno_values = array(); } $t_object->set('idno', join($vs_sep, $va_idno_values)); // true=always set serial values, even if they already have a value; this let's us use the original pattern while replacing the serial value every time through break; } $t_object->insert(); if ($t_object->numErrors()) { $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Error creating new object while importing {$f} from {$vs_relative_directory}: " . join('; ', $t_object->getErrors()))); $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'errors' => $t_object->errors(), 'message' => _t("Error creating new object while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_object->getErrors())), 'status' => 'ERROR'); $o_trans->rollback(); continue; } $t_object->addLabel(array('name' => $f), $vn_locale_id, null, true); if ($t_object->numErrors()) { $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Error creating object label while importing {$f} from {$vs_relative_directory}: " . join('; ', $t_object->getErrors()))); $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'errors' => $t_object->errors(), 'message' => _t("Error creating object label while importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_object->getErrors())), 'status' => 'ERROR'); $o_trans->rollback(); continue; } $t_new_rep = $t_object->addRepresentation($vs_directory . '/' . $f, $vn_rep_type_id, $vn_locale_id, $vn_object_representation_status, $vn_object_representation_access, true, array(), array('original_filename' => $f, 'returnRepresentation' => true)); if ($t_object->numErrors()) { $o_eventlog->log(array("CODE" => 'ERR', "SOURCE" => "mediaImport", "MESSAGE" => "Error importing {$f} from {$vs_relative_directory}: " . join('; ', $t_object->getErrors()))); $va_errors[$vs_relative_directory . '/' . $f] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'errors' => $t_object->errors(), 'message' => _t("Error importing %1 from %2: %3", $f, $vs_relative_directory, join('; ', $t_object->getErrors())), 'status' => 'ERROR'); $o_trans->rollback(); continue; } else { if ($vb_delete_media_on_import) { @unlink($vs_directory . '/' . $f); } } } } if ($t_object->getPrimaryKey()) { $va_notices[$t_object->getPrimaryKey()] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $t_object->getLabelForDisplay(), 'message' => _t('Imported %1 as %2', $f, $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD'))), 'status' => 'SUCCESS'); if ($vn_set_id) { $t_set->addItem($t_object->getPrimaryKey(), null, $po_request->getUserID()); } $o_log->addItem($t_object->getPrimaryKey(), $t_object->getErrors()); // Create relationships? if (is_array($va_create_relationship_for) && sizeof($va_create_relationship_for) && is_array($va_extracted_idnos_from_filename) && sizeof($va_extracted_idnos_from_filename)) { foreach ($va_extracted_idnos_from_filename as $vs_idno) { foreach ($va_create_relationship_for as $vs_rel_table) { if (!isset($va_relationship_type_id_for[$vs_rel_table]) || !$va_relationship_type_id_for[$vs_rel_table]) { continue; } $t_rel = $t_object->getAppDatamodel()->getInstanceByTableName($vs_rel_table); if ($t_rel->load(array($t_rel->getProperty('ID_NUMBERING_ID_FIELD') => $vs_idno))) { $t_object->addRelationship($vs_rel_table, $t_rel->getPrimaryKey(), $va_relationship_type_id_for[$vs_rel_table]); if (!$t_object->numErrors()) { $va_notices[$t_object->getPrimaryKey() . '_rel'] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $vs_label = $t_object->getLabelForDisplay(), 'message' => _t('Added relationship between <em>%1</em> and %2 <em>%3</em>', $vs_label, $t_rel->getProperty('NAME_SINGULAR'), $t_rel->getLabelForDisplay()), 'status' => 'RELATED'); } else { $va_notices[$t_object->getPrimaryKey()] = array('idno' => $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), 'label' => $vs_label = $t_object->getLabelForDisplay(), 'message' => _t('Could not add relationship between <em>%1</em> and %2 <em>%3</em>: %4', $vs_label, $t_rel->getProperty('NAME_SINGULAR'), $t_rel->getLabelForDisplay(), join("; ", $t_object->getErrors())), 'status' => 'ERROR'); } } } } } } else { $va_notices[$vs_relative_directory . '/' . $f] = array('idno' => '', 'label' => $f, 'message' => $vs_import_mode == 'ALWAYS_MATCH' ? _t('Skipped %1 from %2 because it could not be matched', $f, $vs_relative_directory) : _t('Skipped %1 from %2', $f, $vs_relative_directory), 'status' => 'SKIPPED'); } if (isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) { $ps_callback($po_request, $vn_c, $vn_num_items, _t("[%3/%4] Processing %1 (%3)", caTruncateStringWithEllipsis($vs_relative_directory, 20) . '/' . caTruncateStringWithEllipsis($f, 30), $t_object->get($t_object->getProperty('ID_NUMBERING_ID_FIELD')), $vn_c, $vn_num_items), $t_new_rep, time() - $vn_start_time, memory_get_usage(true), sizeof($va_notices), sizeof($va_errors)); } $vn_c++; } if (isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) { $ps_callback($po_request, $vn_num_items, $vn_num_items, _t("Processing completed"), null, time() - $vn_start_time, memory_get_usage(true), sizeof($va_notices), sizeof($va_errors)); } $vn_elapsed_time = time() - $vn_start_time; if (isset($pa_options['reportCallback']) && ($ps_callback = $pa_options['reportCallback'])) { $va_general = array('elapsedTime' => $vn_elapsed_time, 'numErrors' => sizeof($va_errors), 'numProcessed' => sizeof($va_notices), 'batchSize' => $vn_num_items, 'table' => 'ca_objects', 'set_id' => $t_set->getPrimaryKey(), 'setName' => $t_set->getLabelForDisplay()); $ps_callback($po_request, $va_general, $va_notices, $va_errors); } $o_log->close(); if ($vb_we_set_transaction) { if (sizeof($va_errors) > 0) { $o_trans->rollback(); } else { $o_trans->commit(); } } $vs_set_name = $t_set->getLabelForDisplay(); $vs_started_on = caGetLocalizedDate($vn_start_time); if (isset($pa_options['sendMail']) && $pa_options['sendMail']) { if ($vs_email = trim($po_request->user->get('email'))) { caSendMessageUsingView($po_request, array($vs_email => $po_request->user->get('fname') . ' ' . $po_request->user->get('lname')), __CA_ADMIN_EMAIL__, _t('[%1] Batch media import completed', $po_request->config->get('app_display_name')), 'batch_media_import_completed.tpl', array('notices' => $va_notices, 'errors' => $va_errors, 'directory' => $vs_relative_directory, 'numErrors' => sizeof($va_errors), 'numProcessed' => sizeof($va_notices), 'subjectNameSingular' => _t('file'), 'subjectNamePlural' => _t('files'), 'startedOn' => $vs_started_on, 'completedOn' => caGetLocalizedDate(time()), 'setName' => $vn_set_id ? $vs_set_name : null, 'elapsedTime' => caFormatInterval($vn_elapsed_time))); } } if (isset($pa_options['sendSMS']) && $pa_options['sendSMS']) { SMS::send($po_request->getUserID(), _t("[%1] Media import processing for directory %2 with %3 %4 begun at %5 is complete", $po_request->config->get('app_display_name'), $vs_relative_directory, $vn_num_items, $vn_num_items == 1 ? _t('file') : _t('files'), $vs_started_on)); } return array('errors' => $va_errors, 'notices' => $va_notices, 'processing_time' => caFormatInterval($vn_elapsed_time)); }
/** * Removes specified set from database * * @param int $set_id * @return boolean * @throws SoapFault */ public function removeSet($set_id) { $t_set = new ca_sets(); if (!$t_set->load($set_id)) { throw new SoapFault("Server", "Invalid set_id"); } $t_set->setMode(ACCESS_WRITE); $t_set->delete(); if ($t_set->numErrors() == 0) { return true; } else { throw new SoapFault("Server", "There were errors while deleting the set: " . join(";", $t_set->getErrors())); } }