public function DoCheck() { AssetLoadManager::register('tableList'); // Search engine $vo_search_config_settings = SearchEngine::checkPluginConfiguration(); $this->view->setVar('search_config_settings', $vo_search_config_settings); $this->view->setVar('search_config_engine_name', SearchEngine::getPluginEngineName()); // Media $t_media = new Media(); $va_plugin_names = $t_media->getPluginNames(); $va_plugins = array(); foreach ($va_plugin_names as $vs_plugin_name) { if ($va_plugin_status = $t_media->checkPluginStatus($vs_plugin_name)) { $va_plugins[$vs_plugin_name] = $va_plugin_status; } } $this->view->setVar('media_config_plugin_list', $va_plugins); // PDF Rendering $t_pdf_renderer = new PDFRenderer(); $va_plugin_names = PDFRenderer::getAvailablePDFRendererPlugins(); $va_plugins = array(); foreach ($va_plugin_names as $vs_plugin_name) { if ($va_plugin_status = $t_pdf_renderer->checkPluginStatus($vs_plugin_name)) { $va_plugins[$vs_plugin_name] = $va_plugin_status; } } $this->view->setVar('pdf_renderer_config_plugin_list', $va_plugins); // Application plugins $va_plugin_names = ApplicationPluginManager::getPluginNames(); $va_plugins = array(); foreach ($va_plugin_names as $vs_plugin_name) { if ($va_plugin_status = ApplicationPluginManager::checkPluginStatus($vs_plugin_name)) { $va_plugins[$vs_plugin_name] = $va_plugin_status; } } $this->view->setVar('application_config_plugin_list', $va_plugins); // Barcode generation $vb_gd_is_available = caMediaPluginGDInstalled(true); $va_barcode_components = array(); $va_gd = array('name' => 'GD', 'description' => _t('GD is a graphics processing library required for all barcode generation.')); if (!$vb_gd_is_available) { $va_gd['errors'][] = _t('Is not installed; barcode printing will not be possible.'); } $va_gd['available'] = $vb_gd_is_available; $va_barcode_components['GD'] = $va_gd; $this->view->setVar('barcode_config_component_list', $va_barcode_components); // General system configuration issues if (!(bool) $this->request->config->get('dont_do_expensive_configuration_checks_in_web_ui')) { ConfigurationCheck::performExpensive(); if (ConfigurationCheck::foundErrors()) { $this->view->setVar('configuration_check_errors', ConfigurationCheck::getErrors()); } } $this->render('config_check_html.php'); }
/** * Creates links to the appropriate editor (in Providence) or detail page (in Pawtucket) from supplied text and ids. * Used in SearchResult::get() and BundlableLabelableBaseModelWithAttributes::get() to automatically generate links when fetching * information from related tables. * * @param array $pa_text An array of strings to create links for * @param string $ps_table_name The name of the table/record to which the links refer * @param array $pa_row_ids Array of row_ids to link to. Values must correspond by index with those in $pa_text * @param string $ps_class Optional CSS class to apply to links * @param string $ps_target * @param array $pa_options Supported options are: * requireLinkTags = if set then links are only added when explicitly defined with <l> tags. Default is to make the entire text a link in the absence of <l> tags. * addRelParameter = * * @return array A list of HTML links */ function caCreateLinksFromText($pa_text, $ps_table_name, $pa_row_ids, $ps_class = null, $ps_target = null, $pa_options = null) { if (!in_array(__CA_APP_TYPE__, array('PROVIDENCE', 'PAWTUCKET'))) { return $pa_text; } if (__CA_APP_TYPE__ == 'PAWTUCKET') { $o_config = Configuration::load(); } $pb_add_rel = caGetOption('addRelParameter', $pa_options, false); $vb_can_handle_target = false; if ($ps_target) { $o_app_plugin_manager = new ApplicationPluginManager(); $vb_can_handle_target = $o_app_plugin_manager->hookCanHandleGetAsLinkTarget(array('target' => $ps_target)); } // Parse template $o_dom = new DOMDocument('1.0', 'utf-8'); $o_dom->preserveWhiteSpace = true; libxml_use_internal_errors(true); // don't reported mangled HTML errors $va_links = array(); global $g_request; if (!$g_request) { return $pa_text; } foreach ($pa_text as $vn_i => $vs_text) { $vs_text = preg_replace("!([A-Za-z0-9]+)='([^']*)'!", "\$1=\"\$2\"", $vs_text); // DomDcoument converts single quotes around attributes to double quotes so we do the same to the template $vs_text = preg_replace("![ ]+/>!", "/>", $vs_text); $vs_text = preg_replace("![\r\n]+!", "", $vs_text); // DomDocument removes newlines so we do the same here to the template $o_dom->loadHTML('<?xml encoding="utf-8">' . mb_convert_encoding($vs_text, 'HTML-ENTITIES', 'UTF-8')); // Needs XML declaration to force it to consider the text as UTF-8. Please don't ask why. No one knows. $o_dom->encoding = 'utf-8'; libxml_clear_errors(); $va_l_tags = array(); $o_links = $o_dom->getElementsByTagName("l"); // l=link foreach ($o_links as $o_link) { if (!$o_link) { continue; } $vs_html = $o_dom->saveXML($o_link); $vs_content = preg_replace("!^<[^\\>]+>!", "", $vs_html); $vs_content = preg_replace("!<[^\\>]+>\$!", "", $vs_content); $va_l_tags[] = array('directive' => html_entity_decode($vs_html), 'content' => $vs_content); //html_entity_decode } if (sizeof($va_l_tags)) { $vs_content = html_entity_decode($vs_text); $vs_content = preg_replace_callback("/(&#[0-9]+;)/", function ($m) { return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES"); }, $vs_content); foreach ($va_l_tags as $va_l) { if ($vb_can_handle_target) { $va_params = array('request' => $g_request, 'content' => $va_l['content'], 'table' => $ps_table_name, 'id' => $pa_row_ids[$vn_i], 'classname' => $ps_class, 'target' => $ps_target, 'additionalParameters' => null, 'options' => null); $va_params = $o_app_plugin_manager->hookGetAsLink($va_params); $vs_link_text = $va_params['tag']; } else { switch (__CA_APP_TYPE__) { case 'PROVIDENCE': $vs_link_text = caEditorLink($g_request, $va_l['content'], $ps_class, $ps_table_name, $pa_row_ids[$vn_i], $pb_add_rel ? array('rel' => true) : array()); break; case 'PAWTUCKET': $vs_link_text = caDetailLink($g_request, $va_l['content'], $ps_class, $ps_table_name, $pa_row_ids[$vn_i]); break; } } if ($vs_link_text) { $vs_content = str_replace($va_l['directive'], $vs_link_text, $vs_content); } else { $vs_content = str_replace($va_l['directive'], $va_l['content'], $vs_content); } } $va_links[] = $vs_content; } else { if (isset($pa_options['requireLinkTags']) && $pa_options['requireLinkTags']) { $va_links[] = $vs_text; continue; } if ($vb_can_handle_target) { $va_params = array('request' => $g_request, 'content' => $vs_text, 'table' => $ps_table_name, 'id' => $pa_row_ids[$vn_i], 'classname' => $ps_class, 'target' => $ps_target, 'additionalParameters' => null, 'options' => null); $va_params = $o_app_plugin_manager->hookGetAsLink($va_params); $va_links[] = $va_params['tag']; } else { switch (__CA_APP_TYPE__) { case 'PROVIDENCE': $va_links[] = ($vs_link = caEditorLink($g_request, $vs_text, $ps_class, $ps_table_name, $pa_row_ids[$vn_i])) ? $vs_link : $vs_text; break; case 'PAWTUCKET': $va_links[] = ($vs_link = caDetailLink($g_request, $vs_text, $ps_class, $ps_table_name, $pa_row_ids[$vn_i])) ? $vs_link : $vs_text; break; default: $va_links[] = $vs_text; break; } } } } return $va_links; }
/** * Creates links to the appropriate editor (in Providence) or detail page (in Pawtucket) from supplied text and ids. * Used in SearchResult::get() and BundlableLabelableBaseModelWithAttributes::get() to automatically generate links when fetching * information from related tables. * * @param array $pa_text An array of strings to create links for * @param string $ps_table_name The name of the table/record to which the links refer * @param array $pa_row_ids Array of row_ids to link to. Values must correspond by index with those in $pa_text * @param string $ps_class Optional CSS class to apply to links * @param array $pa_options Supported options are: * requireLinkTags = if set then links are only added when explicitly defined with <l> tags. Default is to make the entire text a link in the absence of <l> tags. * * @return array A list of HTML links */ function caCreateLinksFromText($pa_text, $ps_table_name, $pa_row_ids, $ps_class = null, $ps_target = null, $pa_options = null) { if (!in_array(__CA_APP_TYPE__, array('PROVIDENCE', 'PAWTUCKET'))) { return $pa_text; } if (__CA_APP_TYPE__ == 'PAWTUCKET') { $o_config = Configuration::load(); } $vb_can_handle_target = false; if ($ps_target) { $o_app_plugin_manager = new ApplicationPluginManager(); $vb_can_handle_target = $o_app_plugin_manager->hookCanHandleGetAsLinkTarget(array('target' => $ps_target)); } // Parse template $o_dom = new DOMDocument('1.0', 'utf-8'); $o_dom->preserveWhiteSpace = true; libxml_use_internal_errors(true); // don't reported mangled HTML errors $o_dm = Datamodel::load(); $va_links = $va_type_ids = array(); if ($t_instance = $o_dm->getInstanceByTableName($ps_table_name)) { $va_type_ids = $t_instance->getFieldValuesForIDs($pa_row_ids, array('type_id')); //if (caUseIdentifiersInUrls()) { // $pa_row_ids = array_values($t_instance->getFieldValuesForIDs($pa_row_ids, array($t_instance->getProperty('ID_NUMBERING_ID_FIELD')))); //} } global $g_request; if (!$g_request) { return $pa_text; } foreach ($pa_text as $vn_i => $vs_text) { $vs_text = preg_replace("!([A-Za-z0-9]+)='([^']*)'!", "\$1=\"\$2\"", $vs_text); // DomDcoument converts single quotes around attributes to double quotes so we do the same to the template $vs_text = preg_replace("![ ]+/>!", "/>", $vs_text); // DomDocument removes spaces before the end of self-closing tags so we do the same here to the template $o_dom->loadHTML('<?xml encoding="utf-8">' . $vs_text); // Needs XML declaration to force it to consider the text as UTF-8. Please don't ask why. No one knows. libxml_clear_errors(); $va_l_tags = array(); $o_links = $o_dom->getElementsByTagName("l"); // l=link foreach ($o_links as $o_link) { if (!$o_link) { continue; } $vs_html = $o_dom->saveXML($o_link); $vs_content = preg_replace("!^<[^\\>]+>!", "", $vs_html); $vs_content = preg_replace("!<[^\\>]+>\$!", "", $vs_content); $va_l_tags[] = array('directive' => html_entity_decode($vs_html), 'content' => $vs_content); } if (sizeof($va_l_tags)) { $vs_content = $vs_text; foreach ($va_l_tags as $va_l) { if ($vb_can_handle_target) { $va_params = array('request' => $g_request, 'content' => $va_l['content'], 'table' => $ps_table_name, 'id' => $pa_row_ids[$vn_i], 'classname' => $ps_class, 'target' => $ps_target, 'additionalParameters' => null, 'options' => null); $va_params = $o_app_plugin_manager->hookGetAsLink($va_params); $vs_link_text = $va_params['tag']; } else { switch (__CA_APP_TYPE__) { case 'PROVIDENCE': $vs_link_text = caEditorLink($g_request, $va_l['content'], $ps_class, $ps_table_name, $pa_row_ids[$vn_i]); break; case 'PAWTUCKET': $vs_link_text = caDetailLink($g_request, $va_l['content'], $ps_class, $ps_table_name, $pa_row_ids[$vn_i], array(), array(), array('type_id' => $va_type_ids[$pa_row_ids[$vn_i]])); break; } } if ($vs_link_text) { $vs_content = str_replace($va_l['directive'], $vs_link_text, $vs_content); } else { $vs_content = str_replace($va_l['directive'], $va_l['content'], $vs_content); } } $va_links[] = $vs_content; } else { if (isset($pa_options['requireLinkTags']) && $pa_options['requireLinkTags']) { $va_links[] = $vs_text; continue; } if ($vb_can_handle_target) { $va_params = array('request' => $g_request, 'content' => $vs_text, 'table' => $ps_table_name, 'id' => $pa_row_ids[$vn_i], 'classname' => $ps_class, 'target' => $ps_target, 'additionalParameters' => null, 'options' => null); $va_params = $o_app_plugin_manager->hookGetAsLink($va_params); $va_links[] = $va_params['tag']; } else { switch (__CA_APP_TYPE__) { case 'PROVIDENCE': $va_links[] = ($vs_link = caEditorLink($g_request, $vs_text, $ps_class, $ps_table_name, $pa_row_ids[$vn_i])) ? $vs_link : $vs_text; break; case 'PAWTUCKET': $va_links[] = ($vs_link = caDetailLink($g_request, $vs_text, $ps_class, $ps_table_name, $pa_row_ids[$vn_i], array(), array(), array('type_id' => $va_type_ids[$pa_row_ids[$vn_i]]))) ? $vs_link : $vs_text; break; default: $va_links[] = $vs_text; break; } } } } return $va_links; }
private function preprocess($ps_expression) { // Trigger TimeExpressionParser preprocess hook $o_app_plugin_manager = new ApplicationPluginManager(); $va_hook_result = $o_app_plugin_manager->hookTimeExpressionParserPreprocessBefore(array("expression" => $ps_expression)); if ($va_hook_result["expression"] != $ps_expression) { $ps_expression = $va_hook_result["expression"]; } # convert $va_dict = $this->opo_datetime_settings->getAssoc("expressions"); $vs_lc_expression = mb_strtolower($ps_expression); if (isset($va_dict[$vs_lc_expression])) { $ps_expression = $va_dict[$vs_lc_expression]; } # remove commas $ps_expression = str_replace(',', ' ', $ps_expression); $ps_expression = preg_replace('![ ]+!', ' ', $ps_expression); # remove articles $definiteArticles = $this->opo_language_settings->getList("definiteArticles"); if (sizeof($definiteArticles)) { $ps_expression = " " . $ps_expression . " "; foreach ($definiteArticles as $article) { $ps_expression = str_ireplace(" " . $article . " ", " ", $ps_expression); } } $indefiniteArticles = $this->opo_language_settings->getList("indefiniteArticles"); if (sizeof($indefiniteArticles)) { $ps_expression = " " . $ps_expression . " "; foreach ($indefiniteArticles as $article) { $ps_expression = str_ireplace(" " . $article . " ", " ", $ps_expression); } } $ps_expression = trim($ps_expression); #replace time keywords containing spaces with conf defined replacement, allowing treatments for expression like "av. J.-C." in french $wordsWithSpaces = $this->opo_language_settings->getList("wordsWithSpaces"); $wordsWithSpacesReplacements = $this->opo_language_settings->getList("wordsWithSpacesReplacements"); if (sizeof($wordsWithSpaces) && sizeof($wordsWithSpacesReplacements)) { $ps_expression = str_replace($wordsWithSpaces, $wordsWithSpacesReplacements, $ps_expression); } # separate '?' from words $ps_expression = preg_replace('!([^\\?\\/]+)\\?{1}([^\\?]+)!', '\\1 ? \\2', $ps_expression); $ps_expression = preg_replace('!([^\\?\\/]+)\\?{1}$!', '\\1 ?', $ps_expression); # Remove UTC offset if present $ps_expression = preg_replace("/(T[\\d]{1,2}:[\\d]{2}:[\\d]{2})-[\\d]{1,2}:[\\d]{2}/i", "\$1", $ps_expression); # distinguish w3cdtf dates since we already use '-' for ranges $ps_expression = preg_replace("/([\\d]{4})-([\\d]{2})-([\\d]{2})/", "\$1#\$2#\$3", $ps_expression); # distinguish w3cdtf dates since we already use '-' for ranges $ps_expression = preg_replace("/([\\d]{4})-([\\d]{2})([^\\d\\-\\/\\.]+)/", "\$1#\$2\$3", $ps_expression); # distinguish dd-MMM-yy and dd-MMM-yyyy dates since we already use '-' for ranges (ex. 10-JUN-80 or 10-JUN-1980) $ps_expression = preg_replace("/([\\d]{1,2})-([A-Za-z]{3,15})-([\\d]{2,4})/", "\$1#\$2#\$3", $ps_expression); # convert dd-mm-yyyy dates to dd/mm/yyyy to prevent our range conjunction code below doesn't mangle it $ps_expression = preg_replace("/([\\d]{2})-([\\d]{2})-([\\d]{4})/", "\$1/\$2/\$3", $ps_expression); if (preg_match("/([\\d]{4})-([\\d]{2})\$/", $ps_expression, $va_matches)) { if (intval($va_matches[2]) > 12) { $ps_expression = preg_replace("/([\\d]{4})-([\\d]{2})\$/", "\$1-" . substr($va_matches[1], 0, 2) . "\$2", $ps_expression); } else { $ps_expression = preg_replace("/([\\d]{4})-([\\d]{2})\$/", "\$1#\$2", $ps_expression); } } # process 6-number year ranges # replace '-' used to express decades (eg. 192-) and centuries (eg. 19--) with underscores since we use '-' for ranges if (preg_match('![\\d]{4}\\-!', $ps_expression)) { $ps_expression = preg_replace("![\\-]{1}!", " - ", $ps_expression); } else { $ps_expression = preg_replace('!([\\d]{2})[\\-]{2}!', '\\1__', $ps_expression); $ps_expression = preg_replace('!([\\d]{3})[\\-]{1}$!', '\\1_', $ps_expression); $ps_expression = preg_replace('!([\\d]{3})[\\-]{1}[\\D]+!', '\\1_', $ps_expression); } if (!preg_match("!^[\\-]{1}[\\d]+\$!", $ps_expression)) { $ps_expression = preg_replace("![\\-\\–\\—]{1}!", " - ", $ps_expression); } $va_era_list = array_merge(array_keys($this->opo_language_settings->getAssoc("ADBCTable")), array($this->opo_language_settings->get("dateADIndicator"), $this->opo_language_settings->get("dateBCIndicator"))); foreach ($va_era_list as $vs_era) { $ps_expression = preg_replace("/([\\d]+)" . $vs_era . "[ ]*/i", "\$1 {$vs_era} ", $ps_expression); #str_replace($vs_era, " ".$vs_era, $ps_expression); } $va_meridian_list = array_merge(array_keys($this->opo_language_settings->getAssoc("meridianTable")), array($this->opo_language_settings->get("timeAMMeridian"), $this->opo_language_settings->get("timePMMeridian"))); foreach ($va_meridian_list as $vs_meridian) { $ps_expression = preg_replace("/([\\d]+)" . $vs_meridian . "[ ]*/i", "\$1 {$vs_meridian} ", $ps_expression); #str_replace($vs_meridian, " ".$vs_meridian, $ps_expression); } if (is_array($va_after = $this->opo_language_settings->getList("afterQualifier"))) { $vs_primary_after = array_shift($va_after); foreach ($va_after as $vs_after) { $ps_expression = preg_replace("/^{$vs_after}[ ]+/i", "{$vs_primary_after} ", $ps_expression); } } if (is_array($va_before = $this->opo_language_settings->getList("beforeQualifier"))) { $vs_primary_before = array_shift($va_before); foreach ($va_before as $vs_before) { $ps_expression = preg_replace("/^{$vs_before}[ ]+/i", "{$vs_primary_before} ", $ps_expression); } } if (is_array($va_born = $this->opo_language_settings->getList("bornQualifier"))) { $vs_primary_born = array_shift($va_born); foreach ($va_born as $vs_born) { $ps_expression = preg_replace("/^{$vs_born}[ ]+/i", "{$vs_primary_born} ", $ps_expression); } } if (is_array($va_died = $this->opo_language_settings->getList("diedQualifier"))) { $vs_primary_died = array_shift($va_died); foreach ($va_died as $vs_died) { $ps_expression = preg_replace("/^{$vs_died}[ ]+/i", "{$vs_primary_died} ", $ps_expression); } } $va_conjunction_list = $this->opo_language_settings->getList("rangeConjunctions"); foreach ($va_conjunction_list as $vs_conjunction) { if (!preg_match("/^[A-Za-z0-9\\-]+\$/", $vs_conjunction)) { // only add spaces around non-alphanumeric conjunctions $ps_expression = str_replace($vs_conjunction, ' ' . $vs_conjunction . ' ', $ps_expression); } } // check for ISO 8601 date/times... if we find one split the time off into a separate token $va_datetime_conjunctions = $this->opo_language_settings->getList('dateTimeConjunctions'); $ps_expression = preg_replace("/([\\d]+)T([\\d]+)/i", "\$1 " . $va_datetime_conjunctions[0] . " \$2", $ps_expression); // support year ranges in the form yyyy/yyyy $ps_expression = preg_replace("!^([\\d]{4})/([\\d]{4})\$!", "\$1 - \$2", trim($ps_expression)); // support date entry in the form yyyy-mm-dd/yyy-mm-dd (HSP) $ps_expression = preg_replace("/([\\d]{4}#[\\d]{2}#[\\d]{2})\\/([\\d]{4}#[\\d]{2}#[\\d]{2})/", "\$1 - \$2", $ps_expression); // Trigger TimeExpressionParser preprocess hook $va_hook_result = $o_app_plugin_manager->hookTimeExpressionParserPreprocessAfter(array("expression" => $ps_expression)); if ($va_hook_result["expression"] != $ps_expression) { $ps_expression = $va_hook_result["expression"]; } return trim($ps_expression); }
/** * Caches and returns list of all possible actions */ public static function loadRoleActionList() { if (!ca_user_roles::$s_action_list) { $o_config = Configuration::load(); $o_actions_config = Configuration::load(__CA_CONF_DIR__ . '/user_actions.conf'); $vo_datamodel = Datamodel::load(); $va_raw_actions = $o_actions_config->getAssoc('user_actions'); // expand actions that need expanding foreach ($va_raw_actions as $vs_group => $va_group_info) { $va_new_actions = array(); if (!is_array($va_group_info["actions"])) { $va_group_info["actions"] = array(); } foreach ($va_group_info["actions"] as $vs_action_key => $va_action) { if (is_array($va_action["expand_types"]) && strlen($va_action["expand_types"]["table"]) > 0) { $t_instance = $vo_datamodel->getInstanceByTableName($va_action["expand_types"]["table"], true); if (method_exists($t_instance, "getTypeList")) { $va_type_list = $t_instance->getTypeList(); foreach ($va_type_list as $vn_type_id => $va_type) { $vs_descr_app = str_replace("%t", """ . $va_type["name_singular"] . """, $va_action["expand_types"]["description_appendix"]); $vs_label_app = str_replace("%t", """ . $va_type["name_singular"] . """, $va_action["expand_types"]["label_appendix"]); $va_new_actions[$vs_action_key . "_type:{$t_instance->tableName()}:{$va_type["idno"]}"] = array("description" => $va_action["description"] . " " . $vs_descr_app, "label" => $va_action["label"] . " " . $vs_label_app); } } } } $va_group_info["actions"] = array_merge($va_group_info["actions"], $va_new_actions); } if (is_array($va_raw_plugin_actions = ApplicationPluginManager::getPluginRoleActions())) { $va_raw_actions['plugins'] = array('label' => 'Plugin actions', 'description' => '', 'actions' => $va_raw_plugin_actions); } if (is_array($va_raw_widget_actions = WidgetManager::getWidgetRoleActions())) { $va_raw_actions['widgets'] = array('label' => 'Widget actions', 'description' => '', 'actions' => $va_raw_widget_actions); } $va_flattened_actions = array(); foreach ($va_raw_actions as $vs_group => $va_group_actions_info) { if (!is_array($va_group_actions_info['actions'])) { $va_group_actions_info['actions'] = array(); } $va_flattened_actions = array_merge($va_flattened_actions, $va_group_actions_info['actions']); } ca_user_roles::$s_action_list = array('raw' => $va_raw_actions, 'flattened' => $va_flattened_actions); } return ca_user_roles::$s_action_list; }
/** * Export a single record using the mapping defined by this exporter and return as string * @param string $ps_exporter_code defines the exporter to use * @param int $pn_record_id Primary key of the record to export. Record type is determined by the table_num field for this exporter. * @param array $pa_options * singleRecord = Gives a signal to the export format implementation that this is a single record export. For certain formats * this might trigger different behavior, for instance the XML export format prepends the item-level output with <?xml ... ?> * in those cases. * rdfMode = Signals the implementation that this is an RDF mode export * logDirectory = path to directory where logs should be written * 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 * logger = Optional ready-to-use instance of KLogger to use for logging/debugging * @return string Exported record as string */ public static function exportRecord($ps_exporter_code, $pn_record_id, $pa_options = array()) { // The variable cache is valid for the whole record export. // It's being modified in ca_data_exporters::processExporterItem // and then reset here if we move on to the next record. ca_data_exporters::$s_variables = array(); $o_log = caGetOption('logger', $pa_options); // only set up new logging facilities if no existing one has been passed down if (!$o_log || !$o_log instanceof KLogger) { $vs_log_dir = caGetOption('logDirectory', $pa_options); if (!file_exists($vs_log_dir) || !is_writable($vs_log_dir)) { $vs_log_dir = caGetTempDirPath(); } if (!($vn_log_level = caGetOption('logLevel', $pa_options))) { $vn_log_level = KLogger::INFO; } $o_log = new KLogger($vs_log_dir, $vn_log_level); } // make sure we pass logger to item processor $pa_options['logger'] = $o_log; ca_data_exporters::$s_instance_cache = array(); $t_exporter = ca_data_exporters::loadExporterByCode($ps_exporter_code); if (!$t_exporter) { $o_log->logError(_t("Failed to load exporter with code '%1' for item with ID %2", $ps_exporter_code, $pn_record_id)); return false; } $o_log->logInfo(_t("Successfully loaded exporter with code '%1' for item with ID %2", $ps_exporter_code, $pn_record_id)); $va_export = array(); foreach ($t_exporter->getTopLevelItems() as $va_item) { $va_export = array_merge($va_export, $t_exporter->processExporterItem($va_item['item_id'], $t_exporter->get('table_num'), $pn_record_id, $pa_options)); } $o_log->logInfo(_t("The export tree for exporter code '%1' and item with ID %2 is now ready to be processed by the export format (i.e. transformed to XML, for example).", $ps_exporter_code, $pn_record_id)); $o_log->logDebug(print_r($va_export, true)); // we may wanna auto-load this? switch ($t_exporter->getSetting('exporter_format')) { case 'XML': $o_export = new ExportXML(); break; case 'MARC': $o_export = new ExportMARC(); break; case 'CSV': $o_export = new ExportCSV(); break; case 'ExifTool': $o_export = new ExportExifTool(); break; default: return; } $o_export->setLogger($o_log); // if someone wants to mangle the whole tree ... well, go right ahead $o_manager = new ApplicationPluginManager(); $o_manager->hookExportRecord(array('exporter_instance' => $t_exporter, 'record_id' => $pn_record_id, 'export' => &$va_export)); $pa_options['settings'] = $t_exporter->getSettings(); $vs_wrap_before = $t_exporter->getSetting('wrap_before_record'); $vs_wrap_after = $t_exporter->getSetting('wrap_after_record'); if ($vs_wrap_before || $vs_wrap_after) { $pa_options['singleRecord'] = false; } $vs_export = $o_export->processExport($va_export, $pa_options); if (strlen($vs_wrap_before) > 0) { $vs_export = $vs_wrap_before . "\n" . $vs_export; } if (strlen($vs_wrap_after) > 0) { $vs_export = $vs_export . "\n" . $vs_wrap_after; } return $vs_export; }
/** * * * @param string $ps_source * @param string $ps_mapping * @param array $pa_options * user_id = user to execute import for * description = Text describing purpose of import to be logged. * showCLIProgressBar = Show command-line progress bar. Default is false. * format = Format of data being imported. MANDATORY * useNcurses = Use ncurses library to format output * logDirectory = path to directory where logs should be written * 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 * dryRun = do import but don't actually save data * environment = an array of environment values to provide to the import process. The keys manifest themselves as mappable tags. * forceImportForPrimaryKeys = list of primary key ids to force mapped source data into. The number of keys passed should equal or exceed the number of rows in the source data. [Default is empty] * transaction = transaction to perform import within. Will not be used if noTransaction option is set. [Default is to create a new transaction] * noTransaction = don't wrap the import in a transaction. [Default is false] */ public static function importDataFromSource($ps_source, $ps_mapping, $pa_options = null) { ca_data_importers::$s_num_import_errors = 0; ca_data_importers::$s_num_records_processed = 0; ca_data_importers::$s_num_records_skipped = 0; ca_data_importers::$s_import_error_list = array(); $opa_app_plugin_manager = new ApplicationPluginManager(); $va_notices = $va_errors = array(); $pb_no_transaction = caGetOption('noTransaction', $pa_options, false, array('castTo' => 'bool')); $pa_force_import_for_primary_keys = caGetOption('forceImportForPrimaryKeys', $pa_options, null); if (!($t_mapping = ca_data_importers::mappingExists($ps_mapping))) { return null; } $o_event = ca_data_import_events::newEvent(isset($pa_options['user_id']) ? $pa_options['user_id'] : null, $pa_options['format'], $ps_source, isset($pa_options['description']) ? $pa_options['description'] : ''); $o_trans = null; if (!$pb_no_transaction) { if (!($o_trans = caGetOption('transaction', $pa_options, null))) { $o_trans = new Transaction(); } $t_mapping->setTransaction($o_trans); } $po_request = caGetOption('request', $pa_options, null); $pb_dry_run = caGetOption('dryRun', $pa_options, false); $pn_file_number = caGetOption('fileNumber', $pa_options, 0); $pn_number_of_files = caGetOption('numberOfFiles', $pa_options, 1); $o_config = Configuration::load(); if (!is_array($pa_options) || !isset($pa_options['logLevel']) || !$pa_options['logLevel']) { $pa_options['logLevel'] = KLogger::INFO; } if (!is_array($pa_options) || !isset($pa_options['logDirectory']) || !$pa_options['logDirectory'] || !file_exists($pa_options['logDirectory'])) { if (!($pa_options['logDirectory'] = $o_config->get('batch_metadata_import_log_directory'))) { $pa_options['logDirectory'] = "."; } } if (!is_writeable($pa_options['logDirectory'])) { $pa_options['logDirectory'] = caGetTempDirPath(); } $o_log = new KLogger($pa_options['logDirectory'], $pa_options['logLevel']); $vb_show_cli_progress_bar = isset($pa_options['showCLIProgressBar']) && $pa_options['showCLIProgressBar'] ? true : false; $o_progress = caGetOption('progressBar', $pa_options, new ProgressBar('WebUI')); if ($vb_show_cli_progress_bar) { $o_progress->setMode('CLI'); $o_progress->set('outputToTerminal', true); } if ($vb_use_ncurses = isset($pa_options['useNcurses']) && $pa_options['useNcurses'] ? true : false) { $vb_use_ncurses = caCLIUseNcurses(); } $vn_error_window_height = null; $vn_max_x = $vn_max_y = null; if ($vb_use_ncurses) { ncurses_init(); $r_screen = ncurses_newwin(0, 0, 0, 0); ncurses_border(0, 0, 0, 0, 0, 0, 0, 0); ncurses_getmaxyx($r_screen, $vn_max_y, $vn_max_x); $vn_error_window_height = $vn_max_y - 8; $r_errors = ncurses_newwin($vn_error_window_height, $vn_max_x - 4, 4, 2); ncurses_wborder($r_errors, 0, 0, 0, 0, 0, 0, 0, 0); ncurses_wattron($r_errors, NCURSES_A_REVERSE); ncurses_mvwaddstr($r_errors, 0, 1, _t(" Recent errors ")); ncurses_wattroff($r_errors, NCURSES_A_REVERSE); $r_progress = ncurses_newwin(3, $vn_max_x - 4, $vn_max_y - 4, 2); ncurses_wborder($r_progress, 0, 0, 0, 0, 0, 0, 0, 0); ncurses_wattron($r_progress, NCURSES_A_REVERSE); ncurses_mvwaddstr($r_progress, 0, 1, _t(" Progress ")); ncurses_wattroff($r_progress, NCURSES_A_REVERSE); $r_status = ncurses_newwin(3, $vn_max_x - 4, 1, 2); ncurses_wborder($r_status, 0, 0, 0, 0, 0, 0, 0, 0); ncurses_wattron($r_status, NCURSES_A_REVERSE); ncurses_mvwaddstr($r_status, 0, 1, _t(" Import status ")); ncurses_wattroff($r_status, NCURSES_A_REVERSE); ncurses_refresh(0); ncurses_wrefresh($r_progress); ncurses_wrefresh($r_errors); ncurses_wrefresh($r_status); } $o_log->logInfo(_t('Started import of %1 using mapping %2', $ps_source, $t_mapping->get("importer_code"))); $t = new Timer(); $vn_start_time = time(); $va_log_import_error_opts = array('startTime' => $vn_start_time, 'window' => $r_errors, 'log' => $o_log, 'request' => $po_request, 'progressCallback' => isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback']) ? $ps_callback : null, 'reportCallback' => isset($pa_options['reportCallback']) && ($ps_callback = $pa_options['reportCallback']) ? $ps_callback : null); global $g_ui_locale_id; // constant locale set by index.php for web requests $vn_locale_id = isset($pa_options['locale_id']) && (int) $pa_options['locale_id'] ? (int) $pa_options['locale_id'] : $g_ui_locale_id; $o_dm = $t_mapping->getAppDatamodel(); $o_progress->start(_t('Reading %1', $ps_source), array('window' => $r_progress)); if ($po_request && isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) { $ps_callback($po_request, $pn_file_number, $pn_number_of_files, $ps_source, 0, 100, _t('Reading %1', $ps_source), time() - $vn_start_time, memory_get_usage(true), 0, ca_data_importers::$s_num_import_errors); } // Open file $ps_format = isset($pa_options['format']) && $pa_options['format'] ? $pa_options['format'] : null; if (!($o_reader = $t_mapping->getDataReader($ps_source, $ps_format))) { ca_data_importers::logImportError(_t("Could not open source %1 (format=%2)", $ps_source, $ps_format), $va_log_import_error_opts); if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } return false; } if (!$o_reader->read($ps_source, array('basePath' => $t_mapping->getSetting('basePath')))) { ca_data_importers::logImportError(_t("Could not read source %1 (format=%2)", $ps_source, $ps_format), $va_log_import_error_opts); if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } return false; } $o_log->logDebug(_t('Finished reading input source at %1 seconds', $t->getTime(4))); $vn_num_items = $o_reader->numRows(); $o_progress->setTotal($vn_num_items); $o_progress->start(_t('Importing from %1', $ps_source), array('window' => $r_progress)); if ($po_request && isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) { $ps_callback($po_request, $pn_file_number, $pn_number_of_files, $ps_source, 0, $vn_num_items, _t('Importing from %1', $ps_source), time() - $vn_start_time, memory_get_usage(true), 0, ca_data_importers::$s_num_import_errors); } // What are we importing? $vn_table_num = $t_mapping->get('table_num'); if (!($t_subject = $o_dm->getInstanceByTableNum($vn_table_num))) { // invalid table if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } return false; } $t_subject->setTransaction($o_trans); $vs_subject_table_name = $t_subject->tableName(); $t_label = $t_subject->getLabelTableInstance(); $t_label->setTransaction($o_trans); $vs_label_display_fld = $t_subject->getLabelDisplayField(); $vs_subject_table = $t_subject->tableName(); $vs_type_id_fld = $t_subject->getTypeFieldName(); $vs_idno_fld = $t_subject->getProperty('ID_NUMBERING_ID_FIELD'); // get mapping rules $va_mapping_rules = $t_mapping->getRules(); // get mapping groups $va_mapping_groups = $t_mapping->getGroups(); $va_mapping_items = $t_mapping->getItems(); // // Mapping-level settings // $vs_type_mapping_setting = $t_mapping->getSetting('type'); $vn_num_initial_rows_to_skip = $t_mapping->getSetting('numInitialRowsToSkip'); if (!in_array($vs_import_error_policy = $t_mapping->getSetting('errorPolicy'), array('ignore', 'stop'))) { $vs_import_error_policy = 'ignore'; } if (!in_array($vs_existing_record_policy = $t_mapping->getSetting('existingRecordPolicy'), array('none', 'skip_on_idno', 'skip_on_preferred_labels', 'merge_on_idno', 'merge_on_preferred_labels', 'merge_on_idno_and_preferred_labels', 'merge_on_idno_with_replace', 'merge_on_preferred_labels_with_replace', 'merge_on_idno_and_preferred_labels_with_replace', 'overwrite_on_idno', 'overwrite_on_preferred_labels', 'overwrite_on_idno_and_preferred_labels'))) { $vs_existing_record_policy = 'none'; } // Analyze mapping for figure out where type, idno, preferred label and other mandatory fields are coming from $vn_type_id_mapping_item_id = $vn_idno_mapping_item_id = null; $va_preferred_label_mapping_ids = array(); $va_mandatory_field_mapping_ids = array(); $va_mandatory_fields = $t_subject->getMandatoryFields(); foreach ($va_mapping_items as $vn_item_id => $va_item) { $vs_destination = $va_item['destination']; if (sizeof($va_dest_tmp = explode(".", $vs_destination)) >= 2) { if ($va_dest_tmp[0] == $vs_subject_table && $va_dest_tmp[1] == 'preferred_labels') { if (isset($va_dest_tmp[2])) { $va_preferred_label_mapping_ids[$vn_item_id] = $va_dest_tmp[2]; } else { $va_preferred_label_mapping_ids[$vn_item_id] = $vs_label_display_fld; } continue; } } switch ($vs_destination) { case 'representation_id': if ($vs_subject_table == 'ca_representation_annotations') { $vn_type_id_mapping_item_id = $vn_item_id; } break; case "{$vs_subject_table}.{$vs_type_id_fld}": $vn_type_id_mapping_item_id = $vn_item_id; break; case "{$vs_subject_table}.{$vs_idno_fld}": $vn_idno_mapping_item_id = $vn_item_id; break; } foreach ($va_mandatory_fields as $vs_mandatory_field) { if ($vs_mandatory_field == $vs_type_id_fld) { continue; } // type is handled separately if ($vs_destination == "{$vs_subject_table}.{$vs_mandatory_field}") { $va_mandatory_field_mapping_ids[$vs_mandatory_field] = $vn_item_id; } } } $va_items_by_group = array(); foreach ($va_mapping_items as $vn_item_id => $va_item) { $va_items_by_group[$va_item['group_id']][$va_item['item_id']] = $va_item; } $o_log->logDebug(_t('Finished analyzing mapping at %1 seconds', $t->getTime(4))); // // Set up environment // $va_environment = caGetOption('environment', $pa_options, array(), array('castTo' => 'array')); if (is_array($va_environment_config = $t_mapping->getEnvironment())) { foreach ($va_environment_config as $vn_i => $va_environment_item) { $va_env_tmp = explode("|", $va_environment_item['value']); if (!($o_env_reader = $t_mapping->getDataReader($ps_source, $ps_format))) { break; } if (!$o_env_reader->read($ps_source, array('basePath' => ''))) { break; } $o_env_reader->nextRow(); switch (sizeof($va_env_tmp)) { case 1: $vs_env_value = $o_env_reader->get($va_environment_item['value'], array('returnAsArray' => false)); break; case 2: $vn_seek = (int) $va_env_tmp[0]; $o_reader->seek($vn_seek > 0 ? $vn_seek - 1 : $vn_seek); $o_env_reader->nextRow(); $vs_env_value = $o_env_reader->get($va_env_tmp[1], array('returnAsArray' => false)); $o_reader->seek(0); break; default: $vs_env_value = $va_environment_item['value']; break; } $va_environment[$va_environment_item['name']] = $vs_env_value; } } // // Run through rows // $vn_row = 0; ca_data_importers::$s_num_records_processed = 0; while ($o_reader->nextRow()) { $va_mandatory_field_values = array(); $vs_preferred_label_for_log = null; if ($vn_row < $vn_num_initial_rows_to_skip) { // skip over initial header rows $vn_row++; continue; } $vn_row++; $t->startTimer(); $o_log->logDebug(_t('Started reading row %1 at %2 seconds', $vn_row, $t->getTime(4))); $t_subject = $o_dm->getInstanceByTableNum($vn_table_num); if ($o_trans) { $t_subject->setTransaction($o_trans); } $t_subject->setMode(ACCESS_WRITE); // Update status display if ($vb_use_ncurses && ca_data_importers::$s_num_records_processed) { ncurses_mvwaddstr($r_status, 1, 2, _t("Items processed/skipped: %1/%2", ca_data_importers::$s_num_records_processed, ca_data_importers::$s_num_records_skipped) . str_repeat(" ", 5) . _t("Errors: %1 (%2)", ca_data_importers::$s_num_import_errors, sprintf("%3.1f", ca_data_importers::$s_num_import_errors / ca_data_importers::$s_num_records_processed * 100) . "%") . str_repeat(" ", 6) . _t("Mapping: %1", $ps_mapping) . str_repeat(" ", 5) . _t("Source: %1", $ps_source) . str_repeat(" ", 5) . date("Y-m-d H:i:s") . str_repeat(" ", 5)); ncurses_refresh(0); ncurses_wrefresh($r_status); } // // Get data for current row // $va_row = array_merge($o_reader->getRow(), $va_environment); // // Apply rules // foreach ($va_mapping_rules as $va_rule) { if (!isset($va_rule['trigger']) || !$va_rule['trigger']) { continue; } if (!isset($va_rule['actions']) || !is_array($va_rule['actions']) || !sizeof($va_rule['actions'])) { continue; } $vm_ret = ExpressionParser::evaluate($va_rule['trigger'], $va_row); if (!ExpressionParser::hadError() && (bool) $vm_ret) { foreach ($va_rule['actions'] as $va_action) { if (!is_array($va_action) && strtolower($va_action) == 'skip') { $va_action = array('action' => 'skip'); } switch ($vs_action_code = strtolower($va_action['action'])) { case 'set': $va_row[$va_action['target']] = $va_action['value']; // TODO: transform value using mapping rules? break; case 'skip': default: if ($vs_action_code != 'skip') { $o_log->logInfo(_t('Row was skipped using rule "%1" with default action because an invalid action ("%2") was specified', $va_rule['trigger'], $vs_action_code)); } else { $o_log->logDebug(_t('Row was skipped using rule "%1" with action "%2"', $va_rule['trigger'], $vs_action_code)); } continue 4; break; } } } } // // Perform mapping and insert // // Get minimal info for imported row (type_id, idno, label) // Get type if ($vn_type_id_mapping_item_id) { // Type is specified in row $vs_type = ca_data_importers::getValueFromSource($va_mapping_items[$vn_type_id_mapping_item_id], $o_reader, array('environment' => $va_environment)); } else { // Type is constant for all rows $vs_type = $vs_type_mapping_setting; } // Get idno $vs_idno = null; if ($vn_idno_mapping_item_id) { // idno is specified in row $vs_idno = ca_data_importers::getValueFromSource($va_mapping_items[$vn_idno_mapping_item_id], $o_reader, array('environment' => $va_environment)); if (isset($va_mapping_items[$vn_idno_mapping_item_id]['settings']['default']) && strlen($va_mapping_items[$vn_idno_mapping_item_id]['settings']['default']) && !strlen($vs_idno)) { $vs_idno = $va_mapping_items[$vn_idno_mapping_item_id]['settings']['default']; } if (!is_array($vs_idno) && $vs_idno[0] == '^' && preg_match("!^\\^[^ ]+\$!", $vs_idno)) { // Parse placeholder when it's at the beginning of the value if (!is_null($vm_parsed_val = BaseRefinery::parsePlaceholder($vs_idno, $va_row, $va_item, null, array('reader' => $o_reader, 'returnAsString' => true)))) { $vs_idno = $vm_parsed_val; } } // Apply prefix/suffix *AFTER* setting default if ($vs_idno && isset($va_mapping_items[$vn_idno_mapping_item_id]['settings']['prefix']) && strlen($va_mapping_items[$vn_idno_mapping_item_id]['settings']['prefix'])) { $vs_idno = $va_mapping_items[$vn_idno_mapping_item_id]['settings']['prefix'] . $vs_idno; } if ($vs_idno && isset($va_mapping_items[$vn_idno_mapping_item_id]['settings']['suffix']) && strlen($va_mapping_items[$vn_idno_mapping_item_id]['settings']['suffix'])) { $vs_idno .= $va_mapping_items[$vn_idno_mapping_item_id]['settings']['suffix']; } if (isset($va_mapping_items[$vn_idno_mapping_item_id]['settings']['formatWithTemplate']) && strlen($va_mapping_items[$vn_idno_mapping_item_id]['settings']['formatWithTemplate'])) { $vs_idno = caProcessTemplate($va_mapping_items[$vn_idno_mapping_item_id]['settings']['formatWithTemplate'], $va_row); } } else { $vs_idno = "%"; } $vb_idno_is_template = (bool) preg_match('![%]+!', $vs_idno); // get preferred labels $va_pref_label_values = array(); foreach ($va_preferred_label_mapping_ids as $vn_preferred_label_mapping_id => $vs_preferred_label_mapping_fld) { $vs_label_val = ca_data_importers::getValueFromSource($va_mapping_items[$vn_preferred_label_mapping_id], $o_reader, array('environment' => $va_environment)); // If a template is specified format the label value with it so merge-on-preferred_label doesn't fail if (isset($va_mapping_items[$vn_preferred_label_mapping_id]['settings']['formatWithTemplate']) && strlen($va_mapping_items[$vn_preferred_label_mapping_id]['settings']['formatWithTemplate'])) { $vs_label_val = caProcessTemplate($va_mapping_items[$vn_preferred_label_mapping_id]['settings']['formatWithTemplate'], $va_row); } $va_pref_label_values[$vs_preferred_label_mapping_fld] = $vs_label_val; } $vs_display_label = isset($va_pref_label_values[$vs_label_display_fld]) ? $va_pref_label_values[$vs_label_display_fld] : $vs_idno; // // Look for existing record? // if (is_array($pa_force_import_for_primary_keys) && sizeof($pa_force_import_for_primary_keys) > 0) { $vn_id = array_shift($pa_force_import_for_primary_keys); if (!$t_subject->load($vn_id)) { $o_log->logInfo(_t('[%1] Skipped import because of forced primary key \'%1\' does not exist', $vn_id)); ca_data_importers::$s_num_records_skipped++; continue; // skip because primary key does not exist } } elseif ($vs_existing_record_policy != 'none') { switch ($vs_existing_record_policy) { case 'skip_on_idno': if (!$vb_idno_is_template) { $va_ids = call_user_func_array($t_subject->tableName() . "::find", array(array('type_id' => $vs_type, $t_subject->getProperty('ID_NUMBERING_ID_FIELD') => $vs_idno, 'deleted' => 0), array('returnAs' => 'ids'))); if (is_array($va_ids) && sizeof($va_ids) > 0) { $o_log->logInfo(_t('[%1] Skipped import because of existing record matched on identifier by policy %2', $vs_idno, $vs_existing_record_policy)); ca_data_importers::$s_num_records_skipped++; continue 2; // skip because idno matched } } break; case 'skip_on_preferred_labels': $va_ids = call_user_func_array($t_subject->tableName() . "::find", array(array('type_id' => $vs_type, 'preferred_labels' => $va_pref_label_values, 'deleted' => 0), array('returnAs' => 'ids'))); if (is_array($va_ids) && sizeof($va_ids) > 0) { $o_log->logInfo(_t('[%1] Skipped import because of existing record matched on label by policy %2', $vs_idno, $vs_existing_record_policy)); ca_data_importers::$s_num_records_skipped++; continue 2; // skip because label matched } break; case 'merge_on_idno_and_preferred_labels': case 'merge_on_idno': case 'merge_on_idno_and_preferred_labels_with_replace': case 'merge_on_idno_with_replace': if (!$vb_idno_is_template) { $va_ids = call_user_func_array($t_subject->tableName() . "::find", array(array('type_id' => $vs_type, $t_subject->getProperty('ID_NUMBERING_ID_FIELD') => $vs_idno, 'deleted' => 0), array('returnAs' => 'ids'))); if (is_array($va_ids) && sizeof($va_ids) > 0) { $t_subject->load($va_ids[0]); $o_log->logInfo(_t('[%1] Merged with existing record matched on identifer by policy %2', $vs_idno, $vs_existing_record_policy)); break; } } if (in_array($vs_existing_record_policy, array('merge_on_idno', 'merge_on_idno_with_replace'))) { break; } // fall through if merge_on_idno_and_preferred_labels // fall through if merge_on_idno_and_preferred_labels case 'merge_on_preferred_labels': case 'merge_on_preferred_labels_with_replace': $va_ids = call_user_func_array($t_subject->tableName() . "::find", array(array('type_id' => $vs_type, 'preferred_labels' => $va_pref_label_values, 'deleted' => 0), array('returnAs' => 'ids'))); if (is_array($va_ids) && sizeof($va_ids) > 0) { $t_subject->load($va_ids[0]); $o_log->logInfo(_t('[%1] Merged with existing record matched on label by policy %2', $vs_idno, $vs_existing_record_policy)); } break; case 'overwrite_on_idno_and_preferred_labels': case 'overwrite_on_idno': if (!$vb_idno_is_template && $vs_idno) { $va_ids = call_user_func_array($t_subject->tableName() . "::find", array(array('type_id' => $vs_type, $t_subject->getProperty('ID_NUMBERING_ID_FIELD') => $vs_idno, 'deleted' => 0), array('returnAs' => 'ids'))); if (is_array($va_ids) && sizeof($va_ids) > 0) { $t_subject->load($va_ids[0]); $t_subject->setMode(ACCESS_WRITE); $t_subject->delete(true, array('hard' => true)); if ($t_subject->numErrors()) { ca_data_importers::logImportError(_t('[%1] Could not delete existing record matched on identifier by policy %2', $vs_idno, $vs_existing_record_policy)); // Don't stop? } else { $o_log->logInfo(_t('[%1] Overwrote existing record matched on identifier by policy %2', $vs_idno, $vs_existing_record_policy)); $t_subject->clear(); break; } } } if ($vs_existing_record_policy == 'overwrite_on_idno') { break; } // fall through if overwrite_on_idno_and_preferred_labels // fall through if overwrite_on_idno_and_preferred_labels case 'overwrite_on_preferred_labels': $va_ids = call_user_func_array($t_subject->tableName() . "::find", array(array('type_id' => $vs_type, 'preferred_labels' => $va_pref_label_values, 'deleted' => 0), array('returnAs' => 'ids'))); if (is_array($va_ids) && sizeof($va_ids) > 0) { $t_subject->load($va_ids[0]); $t_subject->setMode(ACCESS_WRITE); $t_subject->delete(true, array('hard' => true)); if ($t_subject->numErrors()) { ca_data_importers::logImportError(_t('[%1] Could not delete existing record matched on label by policy %2', $vs_idno, $vs_existing_record_policy)); // Don't stop? } else { $o_log->logInfo(_t('[%1] Overwrote existing record matched on label by policy %2', $vs_idno, $vs_existing_record_policy)); break; } $t_subject->clear(); } break; } } $o_progress->next(_t("Importing %1", $vs_idno), array('window' => $r_progress)); if ($po_request && isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) { $ps_callback($po_request, $pn_file_number, $pn_number_of_files, $ps_source, ca_data_importers::$s_num_records_processed, $vn_num_items, _t("[%3/%4] Processing %1 (%2)", caTruncateStringWithEllipsis($vs_display_label, 50), $vs_idno, ca_data_importers::$s_num_records_processed, $vn_num_items), time() - $vn_start_time, memory_get_usage(true), ca_data_importers::$s_num_records_processed, ca_data_importers::$s_num_import_errors); } $vb_output_subject_preferred_label = false; $va_content_tree = array(); foreach ($va_items_by_group as $vn_group_id => $va_items) { $va_group = $va_mapping_groups[$vn_group_id]; $vs_group_destination = $va_group['destination']; $va_group_tmp = explode(".", $vs_group_destination); if (sizeof($va_items) < 2 && sizeof($va_group_tmp) > 2) { array_pop($va_group_tmp); } $vs_target_table = $va_group_tmp[0]; if (!($t_target = $o_dm->getInstanceByTableName($vs_target_table, true))) { // Invalid target table $o_log->logWarn(_t('[%1] Skipped group %2 because target %3 is invalid', $vs_idno, $vn_group_id, $vs_target_table)); continue; } if ($o_trans) { $t_target->setTransaction($o_trans); } $va_group_buf = array(); foreach ($va_items as $vn_item_id => $va_item) { if ($vb_use_as_single_value = caGetOption('useAsSingleValue', $va_item['settings'], false)) { // Force repeating values to be imported as a single value $va_vals = array(ca_data_importers::getValueFromSource($va_item, $o_reader, array('delimiter' => caGetOption('delimiter', $va_item['settings'], ''), 'returnAsArray' => false))); } else { $va_vals = ca_data_importers::getValueFromSource($va_item, $o_reader, array('returnAsArray' => true, 'environment' => $va_environment)); } if (!sizeof($va_vals)) { $va_vals = array(0 => null); } // consider missing values equivalent to blanks // Do value conversions foreach ($va_vals as $vn_i => $vm_val) { if (isset($va_item['settings']['default']) && strlen($va_item['settings']['default']) && !strlen($vm_val)) { $vm_val = $va_item['settings']['default']; } // Apply prefix/suffix *AFTER* setting default if ($vm_val && isset($va_item['settings']['prefix']) && strlen($va_item['settings']['prefix'])) { $vm_val = $va_item['settings']['prefix'] . $vm_val; } if ($vm_val && isset($va_item['settings']['suffix']) && strlen($va_item['settings']['suffix'])) { $vm_val .= $va_item['settings']['suffix']; } if (!is_array($vm_val) && $vm_val[0] == '^' && preg_match("!^\\^[^ ]+\$!", $vm_val)) { // Parse placeholder if (!is_null($vm_parsed_val = BaseRefinery::parsePlaceholder($vm_val, $va_row, $va_item, $vn_i, array('reader' => $o_reader, 'returnAsString' => true)))) { $vm_val = $vm_parsed_val; } } if (isset($va_item['settings']['formatWithTemplate']) && strlen($va_item['settings']['formatWithTemplate'])) { $vm_val = caProcessTemplate($va_item['settings']['formatWithTemplate'], array_replace($va_row, array((string) $va_item['source'] => ca_data_importers::replaceValue($vm_val, $va_item))), array('getFrom' => $o_reader)); } if (isset($va_item['settings']['applyRegularExpressions']) && is_array($va_item['settings']['applyRegularExpressions'])) { if (is_array($va_item['settings']['applyRegularExpressions'])) { foreach ($va_item['settings']['applyRegularExpressions'] as $vn_regex_index => $va_regex) { if (!strlen($va_regex['match'])) { continue; } $vm_val = preg_replace("!" . str_replace("!", "\\!", $va_regex['match']) . "!" . (isset($va_regex['caseSensitive']) && (bool) $va_regex['caseSensitive'] ? '' : 'i'), $va_regex['replaceWith'], $vm_val); } } } $va_vals[$vn_i] = $vm_val; if ($o_reader->valuesCanRepeat()) { $va_row[$va_item['source']][$vn_i] = $va_row[mb_strtolower($va_item['source'])][$vn_i] = $vm_val; } else { $va_row[$va_item['source']] = $va_row[mb_strtolower($va_item['source'])] = $vm_val; } } // Process each value $vn_c = -1; foreach ($va_vals as $vn_i => $vm_val) { $vn_c++; if (isset($va_item['settings']['convertNewlinesToHTML']) && (bool) $va_item['settings']['convertNewlinesToHTML'] && is_string($vm_val)) { $vm_val = nl2br($vm_val); } // Get location in content tree for addition of new content $va_item_dest = explode(".", $va_item['destination']); $vs_item_terminal = $va_item_dest[sizeof($va_item_dest) - 1]; if (isset($va_item['settings']['restrictToTypes']) && is_array($va_item['settings']['restrictToTypes']) && !in_array($vs_type, $va_item['settings']['restrictToTypes'])) { $o_log->logInfo(_t('[%1] Skipped row %2 because of type restriction', $vs_idno, $vn_row)); continue 4; } if (isset($va_item['settings']['skipRowIfEmpty']) && (bool) $va_item['settings']['skipRowIfEmpty'] && !strlen($vm_val)) { $o_log->logInfo(_t('[%1] Skipped row %2 because value for %3 in group %4 is empty', $vs_idno, $vn_row, $vs_item_terminal, $vn_group_id)); continue 4; } if (isset($va_item['settings']['skipRowIfValue']) && is_array($va_item['settings']['skipRowIfValue']) && strlen($vm_val) && in_array($vm_val, $va_item['settings']['skipRowIfValue'])) { $o_log->logInfo(_t('[%1] Skipped row %2 because value for %3 in group %4 matches value %5', $vs_idno, $vn_row, $vs_item_terminal, $vn_group_id)); continue 4; } if (isset($va_item['settings']['skipRowIfNotValue']) && is_array($va_item['settings']['skipRowIfNotValue']) && strlen($vm_val) && !in_array($vm_val, $va_item['settings']['skipRowIfNotValue'])) { $o_log->logInfo(_t('[%1] Skipped row %2 because value for %3 in group %4 is not in list of values', $vs_idno, $vn_row, $vs_item_terminal, $vn_group_id, $vm_val)); continue 4; } if (isset($va_item['settings']['skipGroupIfEmpty']) && (bool) $va_item['settings']['skipGroupIfEmpty'] && !strlen($vm_val)) { $o_log->logInfo(_t('[%1] Skipped group %2 because value for %3 is empty', $vs_idno, $vn_group_id, $vs_item_terminal)); continue 3; } if (isset($va_item['settings']['skipGroupIfExpression']) && strlen(trim($va_item['settings']['skipGroupIfExpression']))) { if ($vm_ret = ExpressionParser::evaluate($va_item['settings']['skipGroupIfExpression'], $va_row)) { $o_log->logInfo(_t('[%1] Skipped group %2 because expression %3 is true', $vs_idno, $vn_group_id, $va_item['settings']['skipGroupIfExpression'])); continue 3; } } if (isset($va_item['settings']['skipGroupIfValue']) && is_array($va_item['settings']['skipGroupIfValue']) && strlen($vm_val) && in_array($vm_val, $va_item['settings']['skipGroupIfValue'])) { $o_log->logInfo(_t('[%1] Skipped group %2 because value for %3 matches value %4', $vs_idno, $vn_group_id, $vs_item_terminal, $vm_val)); continue 3; } if (isset($va_item['settings']['skipGroupIfNotValue']) && is_array($va_item['settings']['skipGroupIfNotValue']) && strlen($vm_val) && !in_array($vm_val, $va_item['settings']['skipGroupIfNotValue'])) { $o_log->logInfo(_t('[%1] Skipped group %2 because value for %3 matches is not in list of values', $vs_idno, $vn_group_id, $vs_item_terminal)); continue 3; } if (isset($va_item['settings']['skipIfExpression']) && strlen(trim($va_item['settings']['skipIfExpression']))) { if ($vm_ret = ExpressionParser::evaluate($va_item['settings']['skipIfExpression'], $va_row)) { $o_log->logInfo(_t('[%1] Skipped mapping because expression %2 is true', $vs_idno, $va_item['settings']['skipIfExpression'])); continue 2; } } if (isset($va_item['settings']['skipIfEmpty']) && (bool) $va_item['settings']['skipIfEmpty'] && !strlen($vm_val)) { $o_log->logInfo(_t('[%1] Skipped mapping because value for %2 is empty', $vs_idno, $vs_item_terminal)); continue 2; } if ($vn_type_id_mapping_item_id && $vn_item_id == $vn_type_id_mapping_item_id) { continue; } if ($vn_idno_mapping_item_id && $vn_item_id == $vn_idno_mapping_item_id) { continue; } if (is_null($vm_val)) { continue; } // Get mapping error policy $vb_item_error_policy_is_default = false; if (!isset($va_item['settings']['errorPolicy']) || !in_array($vs_item_error_policy = $va_item['settings']['errorPolicy'], array('ignore', 'stop'))) { $vs_item_error_policy = 'ignore'; $vb_item_error_policy_is_default = true; } // if (isset($va_item['settings']['relationshipType']) && strlen($vs_rel_type = $va_item['settings']['relationshipType']) && $vs_target_table != $vs_subject_table) { $va_group_buf[$vn_c]['_relationship_type'] = $vs_rel_type; } // Is it a constant value? if (preg_match("!^_CONSTANT_:[\\d]+:(.*)!", $va_item['source'], $va_matches)) { $va_group_buf[$vn_c][$vs_item_terminal] = $va_matches[1]; // Set it and go onto the next item if ($vs_target_table == $vs_subject_table_name && ($vs_k = array_search($vn_item_id, $va_mandatory_field_mapping_ids)) !== false) { $va_mandatory_field_values[$vs_k] = $vm_val; } continue; } // Perform refinery call (if required) per value if (isset($va_item['settings']['refineries']) && is_array($va_item['settings']['refineries'])) { foreach ($va_item['settings']['refineries'] as $vs_refinery) { if (!$vs_refinery) { continue; } if ($o_refinery = RefineryManager::getRefineryInstance($vs_refinery)) { $va_refined_values = $o_refinery->refine($va_content_tree, $va_group, $va_item, $va_row, array('mapping' => $t_mapping, 'source' => $ps_source, 'subject' => $t_subject, 'locale_id' => $vn_locale_id, 'log' => $o_log, 'transaction' => $o_trans, 'importEvent' => $o_event, 'importEventSource' => $vn_row, 'reader' => $o_reader, 'valueIndex' => $vn_i)); if (!$va_refined_values || is_array($va_refined_values) && !sizeof($va_refined_values)) { continue 2; } if ($o_refinery->returnsMultipleValues()) { foreach ($va_refined_values as $va_refined_value) { $va_refined_value['_errorPolicy'] = $vs_item_error_policy; if (!is_array($va_group_buf[$vn_c])) { $va_group_buf[$vn_c] = array(); } $va_group_buf[$vn_c] = array_merge($va_group_buf[$vn_c], $va_refined_value); $vn_c++; } } else { $va_group_buf[$vn_c]['_errorPolicy'] = $vs_item_error_policy; $va_group_buf[$vn_c][$vs_item_terminal] = $va_refined_values; $vn_c++; } if ($vs_target_table == $vs_subject_table_name && ($vs_k = array_search($vn_item_id, $va_mandatory_field_mapping_ids)) !== false) { $va_mandatory_field_values[$vs_k] = $vm_val; } continue 2; } else { ca_data_importers::logImportError(_t('[%1] Invalid refinery %2 specified', $vs_idno, $vs_refinery)); } } } if ($vs_target_table == $vs_subject_table_name && ($vs_k = array_search($vn_item_id, $va_mandatory_field_mapping_ids)) !== false) { $va_mandatory_field_values[$vs_k] = $vm_val; } $vn_max_length = !is_array($vm_val) && isset($va_item['settings']['maxLength']) && (int) $va_item['settings']['maxLength'] ? (int) $va_item['settings']['maxLength'] : null; if (isset($va_item['settings']['delimiter']) && $va_item['settings']['delimiter']) { if (!is_array($va_item['settings']['delimiter'])) { $va_item['settings']['delimiter'] = array($va_item['settings']['delimiter']); } if (sizeof($va_item['settings']['delimiter'])) { foreach ($va_item['settings']['delimiter'] as $vn_index => $vs_delim) { $va_item['settings']['delimiter'][$vn_index] = preg_quote($vs_delim, "!"); } $va_val_list = preg_split("!(" . join("|", $va_item['settings']['delimiter']) . ")!", $vm_val); // Add delimited values foreach ($va_val_list as $vs_list_val) { $vs_list_val = trim(ca_data_importers::replaceValue($vs_list_val, $va_item)); if ($vn_max_length && mb_strlen($vs_list_val) > $vn_max_length) { $vs_list_val = mb_substr($vs_list_val, 0, $vn_max_length); } $va_group_buf[$vn_c] = array($vs_item_terminal => $vs_list_val, '_errorPolicy' => $vs_item_error_policy); $vn_c++; } $vn_row++; continue; // Don't add "regular" value below } } if ($vn_max_length && mb_strlen($vm_val) > $vn_max_length) { $vm_val = mb_substr($vm_val, 0, $vn_max_length); } switch ($vs_item_terminal) { case 'preferred_labels': case 'nonpreferred_labels': if ($t_instance = $o_dm->getInstanceByTableName($vs_target_table, true)) { $va_group_buf[$vn_c][$t_instance->getLabelDisplayField()] = $vm_val; } if ($o_trans) { $t_instance->setTransaction($o_trans); } if (!$vb_item_error_policy_is_default || !isset($va_group_buf[$vn_c]['_errorPolicy'])) { if (is_array($va_group_buf[$vn_c])) { $va_group_buf[$vn_c]['_errorPolicy'] = $vs_item_error_policy; } } if ($vs_item_terminal == 'preferred_labels') { $vs_preferred_label_for_log = $vm_val; } break; default: $va_group_buf[$vn_c][$vs_item_terminal] = $vm_val; if (!$vb_item_error_policy_is_default || !isset($va_group_buf[$vn_c]['_errorPolicy'])) { if (is_array($va_group_buf[$vn_c])) { $va_group_buf[$vn_c]['_errorPolicy'] = $vs_item_error_policy; } } break; } } // end foreach($va_vals as $vm_val) } foreach ($va_group_buf as $vn_group_index => $va_group_data) { $va_ptr =& $va_content_tree; foreach ($va_group_tmp as $vs_tmp) { if (!is_array($va_ptr[$vs_tmp])) { $va_ptr[$vs_tmp] = array(); } $va_ptr =& $va_ptr[$vs_tmp]; if ($vs_tmp == $vs_target_table) { // add numeric index after table to ensure repeat values don't overwrite each other $va_parent =& $va_ptr; $va_ptr[] = array(); $va_ptr =& $va_ptr[sizeof($va_ptr) - 1]; } } $va_ptr = $va_group_data; } } // // Process out self-relationships // if (is_array($va_content_tree[$vs_subject_table])) { $va_self_related_content = array(); foreach ($va_content_tree[$vs_subject_table] as $vn_i => $va_element_data) { if (isset($va_element_data['_relationship_type'])) { $va_self_related_content[] = $va_element_data; unset($va_content_tree[$vs_subject_table][$vn_i]); } } if (sizeof($va_self_related_content) > 0) { $va_content_tree["related.{$vs_subject_table}"] = $va_self_related_content; } } $vn_row++; $o_log->logDebug(_t('Finished building content tree for %1 at %2 seconds', $vs_idno, $t->getTime(4))); $o_log->logDebug(_t("Content tree is\n%1", print_R($va_content_tree, true))); // // Process data in subject record // //print_r($va_content_tree); //die("END\n\n"); //continue; $opa_app_plugin_manager->hookDataImportContentTree(array('mapping' => $t_mapping, 'content_tree' => &$va_content_tree, 'idno' => &$vs_idno, 'transaction' => &$o_trans, 'log' => &$o_log, 'reader' => $o_reader, 'environment' => $va_environment, 'importEvent' => $o_event, 'importEventSource' => $vn_row)); //print_r($va_content_tree); //die("done\n"); if (!sizeof($va_content_tree) && !str_replace("%", "", $vs_idno)) { continue; } if (!$t_subject->getPrimaryKey()) { $o_event->beginItem($vn_row, $t_subject->tableNum(), 'I'); $t_subject->setMode(ACCESS_WRITE); $t_subject->set($vs_type_id_fld, $vs_type); if ($vb_idno_is_template) { $t_subject->setIdnoWithTemplate($vs_idno); } else { $t_subject->set($vs_idno_fld, $vs_idno, array('assumeIdnoForRepresentationID' => true, 'assumeIdnoStubForLotID' => true)); // assumeIdnoStubForLotID forces ca_objects.lot_id values to always be considered as a potential idno_stub first, before use as a ca_objects.lot_id } // Look for parent_id in the content tree $vs_parent_id_fld = $t_subject->getProperty('HIERARCHY_PARENT_ID_FLD'); foreach ($va_content_tree as $vs_table_name => $va_content) { if ($vs_table_name == $vs_subject_table) { foreach ($va_content as $va_element_data) { foreach ($va_element_data as $vs_element => $va_element_content) { switch ($vs_element) { case $vs_parent_id_fld: if ($va_element_content[$vs_parent_id_fld]) { $t_subject->set($vs_parent_id_fld, $va_element_content[$vs_parent_id_fld], array('treatParentIDAsIdno' => true)); } break; } } } } } foreach ($va_mandatory_field_mapping_ids as $vs_mandatory_field => $vn_mandatory_mapping_item_id) { $t_subject->set($vs_mandatory_field, $va_mandatory_field_values[$vs_mandatory_field], array('assumeIdnoStubForLotID' => true)); } $t_subject->insert(); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("Could not insert new record"), array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_import_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to import error policy')); if ($vb_use_ncurses) { ncurses_end(); } $o_event->endItem($t_subject->getPrimaryKey(), __CA_DATA_IMPORT_ITEM_FAILURE__, _t('Failed to import %1', $vs_idno)); if ($o_trans) { $o_trans->rollback(); } return false; } continue; } $o_log->logDebug(_t('Created idno %1 at %2 seconds', $vs_idno, $t->getTime(4))); } else { $o_event->beginItem($vn_row, $t_subject->tableNum(), 'U'); // update $t_subject->setMode(ACCESS_WRITE); if ($vb_idno_is_template) { $t_subject->setIdnoWithTemplate($vs_idno); } else { $t_subject->set($vs_idno_fld, $vs_idno, array('assumeIdnoStubForLotID' => true)); // assumeIdnoStubForLotID forces ca_objects.lot_id values to always be considered as a potential idno_stub first, before use as a ca_objects.lot_di } $t_subject->update(); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("Could not update matched record"), array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_import_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to import error policy')); if ($vb_use_ncurses) { ncurses_end(); } $o_event->endItem($t_subject->getPrimaryKey(), __CA_DATA_IMPORT_ITEM_FAILURE__, _t('Failed to import %1', $vs_idno)); if ($o_trans) { $o_trans->rollback(); } return false; } continue; } $t_subject->clearErrors(); if (sizeof($va_preferred_label_mapping_ids) && $t_subject->getPreferredLabelCount() > 0) { $t_subject->removeAllLabels(__CA_LABEL_TYPE_PREFERRED__); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("Could not update remove preferred labels from matched record"), array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_import_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to import error policy')); if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } $o_event->endItem($t_subject->getPrimaryKey(), __CA_DATA_IMPORT_ITEM_FAILURE__, _t('Failed to import %1', $vs_idno)); return false; } } } $o_log->logDebug(_t('Updated idno %1 at %2 seconds', $vs_idno, $t->getTime(4))); } if ($vs_idno_fld && ($o_idno = $t_subject->getIDNoPlugInInstance())) { $va_values = $o_idno->htmlFormValuesAsArray($vs_idno_fld, $t_subject->get($vs_idno_fld)); if (!is_array($va_values)) { $va_values = array($va_values); } if (($vs_proc_idno = join($o_idno->getSeparator(), $va_values)) && $vs_proc_idno != $vs_idno) { $t_subject->set($vs_idno_fld, $vs_proc_idno); $t_subject->update(); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("Could update idno"), array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_import_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to import error policy')); if ($vb_use_ncurses) { ncurses_end(); } $o_event->endItem($t_subject->getPrimaryKey(), __CA_DATA_IMPORT_ITEM_FAILURE__, _t('Failed to import %1', $vs_idno)); if ($o_trans) { $o_trans->rollback(); } return false; } continue; } } } $va_elements_set_for_this_record = array(); foreach ($va_content_tree as $vs_table_name => $va_content) { if ($vs_table_name == $vs_subject_table) { foreach ($va_content as $vn_i => $va_element_data) { foreach ($va_element_data as $vs_element => $va_element_content) { if (is_array($va_element_content)) { $vs_item_error_policy = $va_element_content['_errorPolicy']; unset($va_element_content['_errorPolicy']); } else { $vs_item_error_policy = null; } $t_subject->clearErrors(); $t_subject->setMode(ACCESS_WRITE); switch ($vs_element) { case 'preferred_labels': $t_subject->addLabel($va_element_content, $vn_locale_id, isset($va_element_content['type_id']) ? $va_element_content['type_id'] : null, true); if ($t_subject->numErrors() == 0) { $vb_output_subject_preferred_label = true; } if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Could not add preferred label to %2. Record was deleted because no preferred label could be applied: ", $vs_idno, $t_subject->tableName()), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); $t_subject->delete(true, array('hard' => false)); if ($vs_import_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to import error policy %1', $vs_import_error_policy)); if ($vb_use_ncurses) { ncurses_end(); } $o_event->endItem($t_subject->getPrimaryKey(), __CA_DATA_IMPORT_ITEM_FAILURE__, _t('Failed to import %1', $vs_idno)); if ($o_trans) { $o_trans->rollback(); } return false; } if ($vs_item_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to mapping error policy')); if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } return false; } continue 5; } break; case 'nonpreferred_labels': $t_subject->addLabel($va_element_content, $vn_locale_id, isset($va_element_content['type_id']) ? $va_element_content['type_id'] : null, false); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Could not add non-preferred label to %2:", $vs_idno, $t_subject->tableName()), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_item_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to mapping error policy')); if ($vb_use_ncurses) { ncurses_end(); } $o_event->endItem($t_subject->getPrimaryKey(), __CA_DATA_IMPORT_ITEM_FAILURE__, _t('Failed to import %1', $vs_idno)); if ($o_trans) { $o_trans->rollback(); } return false; } } break; default: if ($t_subject->hasField($vs_element)) { $t_subject->set($vs_element, $va_element_content[$vs_element], array('assumeIdnoStubForLotID' => true)); $t_subject->update(); break; } if ($vs_subject_table == 'ca_representation_annotations' && $vs_element == 'properties') { foreach ($va_element_content as $vs_prop => $vs_prop_val) { $t_subject->setPropertyValue($vs_prop, $vs_prop_val); } break; } if (is_array($va_element_content)) { $va_element_content['locale_id'] = $vn_locale_id; } if (!isset($va_elements_set_for_this_record[$vs_element]) && !$va_elements_set_for_this_record[$vs_element] && in_array($vs_existing_record_policy, array('merge_on_idno_with_replace', 'merge_on_preferred_labels_with_replace', 'merge_on_idno_and_preferred_labels_with_replace'))) { $t_subject->removeAttributes($vs_element, array('force' => true)); } $va_elements_set_for_this_record[$vs_element] = true; $t_subject->addAttribute($va_element_content, $vs_element, null, array('showRepeatCountErrors' => true, 'alwaysTreatValueAsIdno' => true)); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Failed to add value for %2; values were %3: ", $vs_idno, $vs_element, ca_data_importers::formatValuesForLog($va_element_content)), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_item_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to mapping error policy')); if ($vb_use_ncurses) { ncurses_end(); } $o_event->endItem($t_subject->getPrimaryKey(), __CA_DATA_IMPORT_ITEM_FAILURE__, _t('Failed to import %1', $vs_idno)); if ($o_trans) { $o_trans->rollback(); } return false; } } $t_subject->update(); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Invalid %2; values were %3: ", $vs_idno, $vs_element, ca_data_importers::formatValuesForLog($va_element_content)), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_item_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to mapping error policy')); if ($vb_use_ncurses) { ncurses_end(); } $o_event->endItem($t_subject->getPrimaryKey(), __CA_DATA_IMPORT_ITEM_FAILURE__, _t('Failed to import %1', $vs_idno)); if ($o_trans) { $o_trans->rollback(); } return false; } } break; } } } } else { // related $vs_table_name = preg_replace('!^related\\.!', '', $vs_table_name); foreach ($va_content as $vn_i => $va_element_data) { $va_match_on = caGetOption('_matchOn', $va_element_data, null); $vb_dont_create = caGetOption('_dontCreate', $va_element_data, null); $va_data_for_rel_table = $va_element_data; $va_nonpreferred_labels = isset($va_data_for_rel_table['nonpreferred_labels']) ? $va_data_for_rel_table['nonpreferred_labels'] : null; unset($va_data_for_rel_table['preferred_labels']); unset($va_data_for_rel_table['_relationship_type']); unset($va_data_for_rel_table['_type']); unset($va_data_for_rel_table['_parent_id']); unset($va_data_for_rel_table['_errorPolicy']); unset($va_data_for_rel_table['_matchOn']); $va_data_for_rel_table = array_merge($va_data_for_rel_table, ca_data_importers::_extractIntrinsicValues($va_data_for_rel_table, $vs_table_name)); $t_subject->clearErrors(); switch ($vs_table_name) { case 'ca_objects': if ($vn_rel_id = DataMigrationUtils::getObjectID($va_element_data['preferred_labels']['name'], $va_element_data['_parent_id'], $va_element_data['_type'], $vn_locale_id, $va_data_for_rel_table, array('dontCreate' => $vb_dont_create, 'matchOn' => $va_match_on, 'log' => $o_log, 'transaction' => $o_trans, 'importEvent' => $o_event, 'importEventSource' => $vn_row, 'nonPreferredLabels' => $va_nonpreferred_labels))) { if (!($vs_rel_type = $va_element_data['_relationship_type']) && !($vs_rel_type = $va_element_data['idno']['_relationship_type'])) { break; } $t_subject->addRelationship($vs_table_name, $vn_rel_id, trim($va_element_data['_relationship_type']), null, null, null, null, array('interstitialValues' => $va_element_data['_interstitial'])); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Could not add related object with relationship %2:", $vs_idno, trim($va_element_data['_relationship_type'])), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_item_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to mapping error policy')); if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } return false; } } } break; case 'ca_object_lots': $vs_idno_stub = null; if (is_array($va_element_data['idno_stub'])) { $vs_idno_stub = isset($va_element_data['idno_stub']['idno_stub']) ? $va_element_data['idno_stub']['idno_stub'] : ''; } else { $vs_idno_stub = isset($va_element_data['idno_stub']) ? $va_element_data['idno_stub'] : ''; } if ($vn_rel_id = DataMigrationUtils::getObjectLotID($vs_idno_stub, $va_element_data['preferred_labels']['name'], $va_element_data['_type'], $vn_locale_id, $va_data_for_rel_table, array('dontCreate' => $vb_dont_create, 'matchOn' => $va_match_on, 'log' => $o_log, 'transaction' => $o_trans, 'importEvent' => $o_event, 'importEventSource' => $vn_row, 'nonPreferredLabels' => $va_nonpreferred_labels))) { if (!($vs_rel_type = $va_element_data['_relationship_type']) && !($vs_rel_type = $va_element_data['idno_stub']['_relationship_type'])) { break; } $t_subject->addRelationship($vs_table_name, $vn_rel_id, trim($va_element_data['_relationship_type']), null, null, null, null, array('interstitialValues' => $va_element_data['_interstitial'])); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Could not add related object lot with relationship %2:", $vs_idno, trim($va_element_data['_relationship_type'])), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_item_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to mapping error policy')); if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } return false; } } } break; case 'ca_entities': if ($vn_rel_id = DataMigrationUtils::getEntityID($va_element_data['preferred_labels'], $va_element_data['_type'], $vn_locale_id, $va_data_for_rel_table, array('dontCreate' => $vb_dont_create, 'matchOn' => $va_match_on, 'log' => $o_log, 'transaction' => $o_trans, 'importEvent' => $o_event, 'importEventSource' => $vn_row, 'nonPreferredLabels' => $va_nonpreferred_labels))) { if (!($vs_rel_type = $va_element_data['_relationship_type']) && !($vs_rel_type = $va_element_data['idno']['_relationship_type'])) { break; } $t_subject->addRelationship($vs_table_name, $vn_rel_id, trim($va_element_data['_relationship_type']), null, null, null, null, array('interstitialValues' => $va_element_data['_interstitial'])); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Could not add related entity with relationship %2:", $vs_idno, trim($va_element_data['_relationship_type'])), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_item_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to mapping error policy')); if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } return false; } } } break; case 'ca_places': if ($vn_rel_id = DataMigrationUtils::getPlaceID($va_element_data['preferred_labels']['name'], $va_element_data['_parent_id'], $va_element_data['_type'], $vn_locale_id, $va_data_for_rel_table, array('dontCreate' => $vb_dont_create, 'matchOn' => $va_match_on, 'log' => $o_log, 'transaction' => $o_trans, 'importEvent' => $o_event, 'importEventSource' => $vn_row, 'nonPreferredLabels' => $va_nonpreferred_labels))) { if (!($vs_rel_type = $va_element_data['_relationship_type']) && !($vs_rel_type = $va_element_data['idno']['_relationship_type'])) { break; } $t_subject->addRelationship($vs_table_name, $vn_rel_id, trim($va_element_data['_relationship_type']), null, null, null, null, array('interstitialValues' => $va_element_data['_interstitial'])); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Could not add related place with relationship %2:", $vs_idno, trim($va_element_data['_relationship_type'])), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_item_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to mapping error policy')); if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } return false; } } } break; case 'ca_collections': if ($vn_rel_id = DataMigrationUtils::getCollectionID($va_element_data['preferred_labels']['name'], $va_element_data['_type'], $vn_locale_id, $va_data_for_rel_table, array('dontCreate' => $vb_dont_create, 'matchOn' => $va_match_on, 'log' => $o_log, 'transaction' => $o_trans, 'importEvent' => $o_event, 'importEventSource' => $vn_row, 'nonPreferredLabels' => $va_nonpreferred_labels))) { if (!($vs_rel_type = $va_element_data['_relationship_type']) && !($vs_rel_type = $va_element_data['idno']['_relationship_type'])) { break; } $t_subject->addRelationship($vs_table_name, $vn_rel_id, $vs_rel_type, null, null, null, null, array('interstitialValues' => $va_element_data['_interstitial'])); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Could not add related collection with relationship %2:", $vs_idno, $vs_rel_type), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_item_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to mapping error policy')); if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } return false; } } } break; case 'ca_occurrences': if ($vn_rel_id = DataMigrationUtils::getOccurrenceID($va_element_data['preferred_labels']['name'], $va_element_data['_parent_id'], $va_element_data['_type'], $vn_locale_id, $va_data_for_rel_table, array('dontCreate' => $vb_dont_create, 'matchOn' => $va_match_on, 'log' => $o_log, 'transaction' => $o_trans, 'importEvent' => $o_event, 'importEventSource' => $vn_row, 'nonPreferredLabels' => $va_nonpreferred_labels))) { if (!($vs_rel_type = $va_element_data['_relationship_type']) && !($vs_rel_type = $va_element_data['idno']['_relationship_type'])) { break; } $t_subject->addRelationship($vs_table_name, $vn_rel_id, $vs_rel_type, null, null, null, null, array('interstitialValues' => $va_element_data['_interstitial'])); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Could not add related occurrence with relationship %2:", $vs_idno, $vs_rel_type), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_item_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to mapping error policy')); if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } return false; } } } break; case 'ca_storage_locations': if ($vn_rel_id = DataMigrationUtils::getStorageLocationID($va_element_data['preferred_labels']['name'], $va_element_data['_parent_id'], $va_element_data['_type'], $vn_locale_id, $va_data_for_rel_table, array('dontCreate' => $vb_dont_create, 'matchOn' => $va_match_on, 'log' => $o_log, 'transaction' => $o_trans, 'importEvent' => $o_event, 'importEventSource' => $vn_row, 'nonPreferredLabels' => $va_nonpreferred_labels))) { if (!($vs_rel_type = $va_element_data['_relationship_type']) && !($vs_rel_type = $va_element_data['idno']['_relationship_type'])) { break; } $t_subject->addRelationship($vs_table_name, $vn_rel_id, trim($va_element_data['_relationship_type']), null, null, null, null, array('interstitialValues' => $va_element_data['_interstitial'])); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Could not add related storage location with relationship %2:", $vs_idno, trim($va_element_data['_relationship_type'])), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_item_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to mapping error policy')); if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } return false; } } } break; case 'ca_list_items': $va_data_for_rel_table['is_enabled'] = 1; $va_data_for_rel_table['preferred_labels'] = $va_element_data['preferred_labels']; if ($vn_rel_id = DataMigrationUtils::getListItemID($va_element_data['_list'], $va_element_data['idno'] ? $va_element_data['idno'] : null, $va_element_data['_type'], $vn_locale_id, $va_data_for_rel_table, array('dontCreate' => $vb_dont_create, 'matchOn' => $va_match_on, 'log' => $o_log, 'transaction' => $o_trans, 'importEvent' => $o_event, 'importEventSource' => $vn_row, 'nonPreferredLabels' => $va_nonpreferred_labels))) { if (!($vs_rel_type = $va_element_data['_relationship_type']) && !($vs_rel_type = $va_element_data['idno']['_relationship_type'])) { break; } $t_subject->addRelationship($vs_table_name, $vn_rel_id, trim($va_element_data['_relationship_type']), null, null, null, null, array('interstitialValues' => $va_element_data['_interstitial'])); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Could not add related list item with relationship %2:", $vs_idno, trim($va_element_data['_relationship_type'])), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_item_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to mapping error policy')); if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } return false; } } } break; case 'ca_object_representations': if ($vn_rel_id = DataMigrationUtils::getObjectRepresentationID($va_element_data['preferred_labels']['name'], $va_element_data['_type'], $vn_locale_id, $va_data_for_rel_table, array('dontCreate' => $vb_dont_create, 'matchOn' => $va_match_on, 'log' => $o_log, 'transaction' => $o_trans, 'importEvent' => $o_event, 'importEventSource' => $vn_row, 'nonPreferredLabels' => $va_nonpreferred_labels, 'matchMediaFilesWithoutExtension' => true))) { $t_subject->linkRepresentation($vn_rel_id, null, null, null, null, array('type_id' => trim($va_element_data['_relationship_type']), 'is_primary' => true)); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Could not add related object representation with:", $vs_idno), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_item_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to mapping error policy')); if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } return false; } } } // // if (($vs_subject_table_name == 'ca_objects') && $va_element_data['media']['media']) { // unset($va_data_for_rel_table['media']); // // foreach($va_data_for_rel_table as $vs_key => $vm_val) { // // Attributes, including intrinsics are in two-level format, eg. idno is $va_attributes['idno']['idno'] // // but addRepresentations() expects intrinsics to be single level (eg. $va_attributes['idno']) so // // we do some rewriting here // if (is_array($vm_val) && isset($vm_val[$vs_key])) { // $va_data_for_rel_table[$vs_key] = $vm_val[$vs_key]; // } // } // // if (!($t_subject->addRepresentation($va_element_data['media']['media'], isset($va_element_data['_type']) ? $va_element_data['_type'] : caGetDefaultItemID('object_representation_types'), $vn_locale_id, 0, 0, true, $va_data_for_rel_table, array('dontCreate' => $vb_dont_create, 'matchOn' => $va_match_on)))) { // $vs_error = join("; ", $t_subject->getErrors()); // ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); // if ($vs_item_error_policy == 'stop') { // $o_log->logAlert(_t('Import stopped due to mapping error policy')); // if($vb_use_ncurses) { ncurses_end(); } // if ($o_trans) { $o_trans->rollback(); } // return false; // } // } // } break; case 'ca_loans': if ($vn_rel_id = DataMigrationUtils::getLoanID($va_element_data['preferred_labels']['name'], $va_element_data['_type'], $vn_locale_id, $va_data_for_rel_table, array('dontCreate' => $vb_dont_create, 'matchOn' => $va_match_on, 'log' => $o_log, 'transaction' => $o_trans, 'importEvent' => $o_event, 'importEventSource' => $vn_row, 'nonPreferredLabels' => $va_nonpreferred_labels))) { if (!($vs_rel_type = $va_element_data['_relationship_type']) && !($vs_rel_type = $va_element_data['idno']['_relationship_type'])) { break; } $t_subject->addRelationship($vs_table_name, $vn_rel_id, trim($va_element_data['_relationship_type']), null, null, null, null, array('interstitialValues' => $va_element_data['_interstitial'])); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Could not add related loan with relationship %2:", $vs_idno, trim($va_element_data['_relationship_type'])), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_item_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to mapping error policy')); if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } return false; } } } break; case 'ca_movements': if ($vn_rel_id = DataMigrationUtils::getMovementID($va_element_data['preferred_labels']['name'], $va_element_data['_type'], $vn_locale_id, $va_data_for_rel_table, array('dontCreate' => $vb_dont_create, 'matchOn' => $va_match_on, 'log' => $o_log, 'transaction' => $o_trans, 'importEvent' => $o_event, 'importEventSource' => $vn_row, 'nonPreferredLabels' => $va_nonpreferred_labels))) { if (!($vs_rel_type = $va_element_data['_relationship_type']) && !($vs_rel_type = $va_element_data['idno']['_relationship_type'])) { break; } $t_subject->addRelationship($vs_table_name, $vn_rel_id, trim($va_element_data['_relationship_type']), null, null, null, null, array('interstitialValues' => $va_element_data['_interstitial'])); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Could not add related movement with relationship %2:", $vs_idno, trim($va_element_data['_relationship_type'])), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_item_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to mapping error policy')); if ($vb_use_ncurses) { ncurses_end(); } if ($o_trans) { $o_trans->rollback(); } return false; } } } break; } if (is_array($va_element_data['_related_related']) && sizeof($va_element_data['_related_related'])) { foreach ($va_element_data['_related_related'] as $vs_rel_rel_table => $va_rel_rels) { foreach ($va_rel_rels as $vn_i => $va_rel_rel) { if (!($t_rel_instance = $o_dm->getInstanceByTableName($vs_table_name))) { $o_log->logWarn(_t("[%1] Could not instantiate related table %2", $vs_idno, $vs_table_name)); continue; } if ($o_trans) { $t_rel_instance->setTransaction($o_trans); } if ($t_rel_instance->load($vn_rel_id)) { if ($t_rel_rel = $t_rel_instance->addRelationship($vs_rel_rel_table, $va_rel_rel['id'], $va_rel_rel['_relationship_type'])) { $o_log->logInfo(_t('[%1] Related %2 (%3) to related %4 with relationship %5', $vs_idno, $o_dm->getTableProperty($vs_rel_rel_table, 'NAME_SINGULAR'), $va_rel_rel['id'], $t_rel_instance->getProperty('NAME_SINGULAR'), trim($va_rel_rel['_relationship_type']))); } else { if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Could not add related %2 (%3) to related %4 with relationship %5:", $vs_idno, $o_dm->getTableProperty($vs_rel_rel_table, 'NAME_SINGULAR'), $va_rel_rel['id'], $t_rel_instance->getProperty('NAME_SINGULAR'), trim($va_rel_rel['_relationship_type'])), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); } } } } } } } } } // $t_subject->update(); // // if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Invalid %2; values were %3: ", $vs_idno, 'attributes', ca_data_importers::formatValuesForLog($va_element_content)), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { // ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); // if ($vs_item_error_policy == 'stop') { // $o_log->logAlert(_t('Import stopped due to mapping error policy')); // if($vb_use_ncurses) { ncurses_end(); } // // $o_event->endItem($t_subject->getPrimaryKey(), __CA_DATA_IMPORT_ITEM_FAILURE__, _t('Failed to import %1', $vs_idno)); // // if ($o_trans) { $o_trans->rollback(); } // return false; // } // } // $o_log->logDebug(_t('Finished inserting content tree for %1 at %2 seconds into database', $vs_idno, $t->getTime(4))); if (!$vb_output_subject_preferred_label && $t_subject->getPreferredLabelCount() == 0) { $t_subject->addLabel(array($vs_label_display_fld => '???'), $vn_locale_id, null, true); if ($vs_error = DataMigrationUtils::postError($t_subject, _t("[%1] Could not add default label", $vs_idno), __CA_DATA_IMPORT_ERROR__, array('dontOutputLevel' => true, 'dontPrint' => true))) { ca_data_importers::logImportError($vs_error, $va_log_import_error_opts); if ($vs_import_error_policy == 'stop') { $o_log->logAlert(_t('Import stopped due to import error policy')); if ($vb_use_ncurses) { ncurses_end(); } $o_event->endItem($t_subject->getPrimaryKey(), __CA_DATA_IMPORT_ITEM_FAILURE__, _t('Failed to import %1', $vs_idno)); if ($o_trans) { $o_trans->rollback(); } return false; } } } $o_log->logInfo(_t('[%1] Imported %2 as %3 ', $vs_idno, $vs_preferred_label_for_log, $vs_subject_table_name)); $o_event->endItem($t_subject->getPrimaryKey(), __CA_DATA_IMPORT_ITEM_SUCCESS__, _t('Imported %1', $vs_idno)); ca_data_importers::$s_num_records_processed++; } $o_log->logInfo(_t('Import of %1 completed using mapping %2: %3 imported/%4 skipped/%5 errors', $ps_source, $t_mapping->get('importer_code'), ca_data_importers::$s_num_records_processed, ca_data_importers::$s_num_records_skipped, ca_data_importers::$s_num_import_errors)); //if ($vb_show_cli_progress_bar) { $o_progress->finish(); //} if ($po_request && isset($pa_options['progressCallback']) && ($ps_callback = $pa_options['progressCallback'])) { $ps_callback($po_request, $pn_file_number, $pn_number_of_files, $ps_source, $vn_num_items, $vn_num_items, _t('Import completed'), time() - $vn_start_time, memory_get_usage(true), ca_data_importers::$s_num_records_processed, ca_data_importers::$s_num_import_errors); } if (isset($pa_options['reportCallback']) && ($ps_callback = $pa_options['reportCallback'])) { $va_general = array('elapsedTime' => time() - $vn_start_time, 'numErrors' => ca_data_importers::$s_num_import_errors, 'numProcessed' => ca_data_importers::$s_num_records_processed); $ps_callback($po_request, $va_general, ca_data_importers::$s_import_error_list, true); } if ($vb_use_ncurses) { ncurses_end(); } if ($pb_dry_run) { if ($o_trans) { $o_trans->rollback(); } $o_log->logInfo(_t('Rollback successful import run in "dry run" mode')); } else { if ($o_trans) { $o_trans->commit(); } } return true; }
/** * */ public static function do_configuration_check($po_opts = null) { include_once __CA_LIB_DIR__ . "/core/Search/SearchEngine.php"; include_once __CA_LIB_DIR__ . "/core/Media.php"; include_once __CA_LIB_DIR__ . "/ca/ApplicationPluginManager.php"; include_once __CA_LIB_DIR__ . "/ca/ConfigurationCheck.php"; require_once __CA_LIB_DIR__ . "/core/Configuration.php"; // Media $t_media = new Media(); $va_plugin_names = $t_media->getPluginNames(); CLIUtils::addMessage(_t("Checking media processing plugins..."), array('color' => 'bold_blue')); foreach ($va_plugin_names as $vs_plugin_name) { if ($va_plugin_status = $t_media->checkPluginStatus($vs_plugin_name)) { CLIUtils::addMessage("\t" . _t("Found %1", $vs_plugin_name)); } } CLIUtils::addMessage("\n"); // Application plugins CLIUtils::addMessage(_t("Checking application plugins..."), array('color' => 'bold_blue')); $va_plugin_names = ApplicationPluginManager::getPluginNames(); $va_plugins = array(); foreach ($va_plugin_names as $vs_plugin_name) { if ($va_plugin_status = ApplicationPluginManager::checkPluginStatus($vs_plugin_name)) { CLIUtils::addMessage("\t" . _t("Found %1", $vs_plugin_name)); } } CLIUtils::addMessage("\n"); // Barcode generation CLIUtils::addMessage(_t("Checking for barcode dependencies..."), array('color' => 'bold_blue')); $vb_gd_is_available = caMediaPluginGDInstalled(true); CLIUtils::addMessage("\t(" . _t('GD is a graphics processing library required for all barcode generation.') . ")"); if (!$vb_gd_is_available) { CLIUtils::addError("\t\t" . _t('GD is not installed; barcode printing will not be possible.')); } else { CLIUtils::addMessage("\t\t" . _t('GD is installed; barcode printing will be available.')); } CLIUtils::addMessage("\n"); // General system configuration issues CLIUtils::addMessage(_t("Checking system configuration... this may take a while."), array('color' => 'bold_blue')); ConfigurationCheck::performExpensive(); if (ConfigurationCheck::foundErrors()) { CLIUtils::addMessage("\t" . _t('Errors were found:'), array('color' => 'bold_red')); foreach (ConfigurationCheck::getErrors() as $vn_i => $vs_error) { CLIUtils::addError("\t\t[" . ($vn_i + 1) . "] {$vs_error}"); } } return true; }
public function getHTMLWidgets() { $vs_cur_selection = $this->getDestination(); $va_widgets_config = $this->opa_widgets_config; // fire hook $o_app_plugin_manager = new ApplicationPluginManager(); if ($va_revised_widgets_config = $o_app_plugin_manager->hookRenderWidgets($va_widgets_config)) { $va_widgets_config = $va_revised_widgets_config; } foreach ($va_widgets_config as $vs_key => $va_info) { if (preg_match('!^/' . $va_info['domain']['module'] . '/' . $va_info['domain']['controller'] . '$!i', $vs_cur_selection)) { $va_params = $this->_parseAdditionalParameters($va_info['parameters']); // invoke controller method $vs_classname = ucfirst($va_info['handler']['controller']) . 'Controller'; if (!$va_info['handler']['isplugin']) { if (!(include_once $this->ops_controller_path . '/' . $va_info['handler']['module'] . '/' . $vs_classname . '.php')) { // Invalid controller path $this->postError(2300, _t("Invalid controller path"), "AppNavigation->getHTMLWidgets()"); return false; } } else { if (!(include_once $this->opo_config->get('application_plugins') . '/' . $va_info['handler']['module'] . '/controllers/' . $vs_classname . '.php')) { $this->postError(2300, _t("Invalid controller path"), "AppNavigation->getHTMLWidgets()"); return false; } } $o_action_controller = new $vs_classname($this->opo_request, $this->opo_response, $this->opo_request->config->get('views_directory') . '/' . $va_info['handler']['module']); $vs_output = $o_action_controller->{$va_info['handler']['action']}($va_params); if ($o_action_controller->numErrors()) { return join('; ', $o_action_controller->getErrors()); } return $vs_output; } } return ''; }
/** * Returns list of user actions defined by all plugins * * @return array List of user actions keyed by action code */ public static function getPluginRoleActions() { if ($va_actions = CompositeCache::fetch('role_action_list', 'ApplicationPluginManager')) { return $va_actions; } $va_actions = array(); $o_config = Configuration::load(); $vs_app_plugin_dir = $o_config->get('application_plugins'); $va_app_plugin_dirs = ApplicationPluginManager::getPluginNames(); foreach ($va_app_plugin_dirs as $vs_plugin_dir) { if (!file_exists($vs_app_plugin_dir . '/' . $vs_plugin_dir . '/' . $vs_plugin_dir . 'Plugin.php')) { continue; } require_once $vs_app_plugin_dir . '/' . $vs_plugin_dir . '/' . $vs_plugin_dir . 'Plugin.php'; $vs_plugin_classname = $vs_plugin_dir . 'Plugin'; $va_actions = array_merge($va_actions, call_user_func(array($vs_plugin_classname, 'getRoleActionList'))); } CompositeCache::save('role_action_list', $va_actions, 'ApplicationPluginManager'); return $va_actions; }
/** * Generates HTML for top-level menubar */ public function getHTMLMenuBarAsLinkArray() { $va_nav_info = $this->getNavInfo(0); // get top-level navigation // fire hook $o_app_plugin_manager = new ApplicationPluginManager(); if ($va_revised_nav_info = $o_app_plugin_manager->hookRenderMenuBar($va_nav_info)) { $va_nav_info = $va_revised_nav_info; } $vo_session = $this->opo_request->session; if (intval($this->opo_config->get('do_menu_bar_caching')) > 0 && ($va_menu_cache = $vo_session->getVar('ca_nav_menubar_link_cache'))) { return $va_menu_cache; } $vs_cur_selection = $this->getDestinationAsNavigationPath(); $va_links = array(); foreach ($va_nav_info as $vs_key => $va_menu) { if (!$this->_evaluateRequirements($va_menu['requires'])) { continue; } $va_links[] = caNavLink($this->opo_request, $va_menu['displayName'], '', trim($va_menu['default']['module']), trim($va_menu['default']['controller']), trim($va_menu['default']['action'])); } $vo_session->setVar('ca_nav_menubar_link_cache', $va_links); return $va_links; }
* GNU General Public License. (http://www.gnu.org/copyleft/gpl.html). See * the "license.txt" file for details, or visit the CollectiveAccess web site at * http://www.CollectiveAccess.org * * @package CollectiveAccess * @subpackage tests * @license http://www.gnu.org/copyleft/gpl.html GNU Public License version 3 * * ---------------------------------------------------------------------- */ require_once __CA_BASE_DIR__ . '/tests/plugins/AbstractPluginIntegrationTest.php'; require_once __CA_LIB_DIR__ . '/ca/ApplicationPluginManager.php'; require_once __CA_APP_DIR__ . '/plugins/relationshipGenerator/relationshipGeneratorPlugin.php'; require_once __CA_APP_DIR__ . '/models/ca_collections.php'; // Force initial setup of plugins so it isn't called later, which will overwrite our manually set up plugin ApplicationPluginManager::initPlugins(); /** * Performs an integration test of sorts for the RelationshipGeneratorPlugin. * * See AbstractPluginIntegrationTest for details of the generic cycle of switching in a plugin with test configuration, * creating reference data for the tests, running the tests, then deleting all data generated for the tests. */ class RelationshipGeneratorPluginIntegrationTest extends AbstractPluginIntegrationTest { public static function setUpBeforeClass() { self::_init(); self::_processConfiguration(__DIR__ . '/conf/integration', 'conf/relationshipGenerator.conf.template', 'conf/relationshipGenerator.conf'); self::_switchInTestPlugin('relationshipGenerator', new relationshipGeneratorPlugin(__DIR__ . '/conf/integration')); self::_createRelationshipType('part', 'ca_objects_x_collections'); self::_createListItem('test_object_type1', BaseModel::$s_ca_models_definitions['ca_objects']['FIELDS']['type_id']['LIST_CODE']);
/** * Creates links to the appropriate editor (in Providence) or detail page (in Pawtucket) from supplied text and ids. * Used in SearchResult::get() and BundlableLabelableBaseModelWithAttributes::get() to automatically generate links when fetching * information from related tables. * * @param array $pa_text An array of strings to create links for * @param string $ps_table_name The name of the table/record to which the links refer * @param array $pa_row_ids Array of row_ids to link to. Values must correspond by index with those in $pa_text * @param string $ps_class Optional CSS class to apply to links * @param string $ps_target * @param array $pa_options Supported options are: * requireLinkTags = if set then links are only added when explicitly defined with <l> tags. Default is to make the entire text a link in the absence of <l> tags. * addRelParameter = * * @return array A list of HTML links */ function caCreateLinksFromText($pa_text, $ps_table_name, $pa_row_ids, $ps_class = null, $ps_target = null, $pa_options = null) { if (!in_array(__CA_APP_TYPE__, array('PROVIDENCE', 'PAWTUCKET'))) { return $pa_text; } if (__CA_APP_TYPE__ == 'PAWTUCKET') { $o_config = Configuration::load(); } $pb_add_rel = caGetOption('addRelParameter', $pa_options, false); $vb_can_handle_target = false; if ($ps_target) { $o_app_plugin_manager = new ApplicationPluginManager(); $vb_can_handle_target = $o_app_plugin_manager->hookCanHandleGetAsLinkTarget(array('target' => $ps_target)); } // Parse template $o_doc = str_get_dom($ps_template); $va_links = array(); global $g_request; if (!$g_request) { return $pa_text; } foreach ($pa_text as $vn_i => $vs_text) { $vs_text = preg_replace("!([A-Za-z0-9]+)='([^']*)'!", "\$1=\"\$2\"", $vs_text); $va_l_tags = array(); $o_links = $o_doc('l'); foreach ($o_links as $o_link) { if (!$o_link) { continue; } $vs_html = $o_link->html(); $vs_content = preg_replace("!^<[^\\>]+>!", "", $vs_html); $vs_content = preg_replace("!<[^\\>]+>\$!", "", $vs_content); $va_l_tags[] = array('directive' => html_entity_decode($vs_html), 'content' => $vs_content); //html_entity_decode } if (sizeof($va_l_tags)) { $vs_content = html_entity_decode($vs_text); $vs_content = preg_replace_callback("/(&#[0-9]+;)/", function ($m) { return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES"); }, $vs_content); foreach ($va_l_tags as $va_l) { if ($vb_can_handle_target) { $va_params = array('request' => $g_request, 'content' => $va_l['content'], 'table' => $ps_table_name, 'id' => $pa_row_ids[$vn_i], 'classname' => $ps_class, 'target' => $ps_target, 'additionalParameters' => null, 'options' => null); $va_params = $o_app_plugin_manager->hookGetAsLink($va_params); $vs_link_text = $va_params['tag']; } else { switch (__CA_APP_TYPE__) { case 'PROVIDENCE': $vs_link_text = caEditorLink($g_request, $va_l['content'], $ps_class, $ps_table_name, $pa_row_ids[$vn_i], $pb_add_rel ? array('rel' => true) : array()); break; case 'PAWTUCKET': $vs_link_text = caDetailLink($g_request, $va_l['content'], $ps_class, $ps_table_name, $pa_row_ids[$vn_i]); break; } } if ($vs_link_text) { $vs_content = str_replace($va_l['directive'], $vs_link_text, $vs_content); } else { $vs_content = str_replace($va_l['directive'], $va_l['content'], $vs_content); } } $va_links[] = $vs_content; } else { if (isset($pa_options['requireLinkTags']) && $pa_options['requireLinkTags']) { $va_links[] = $vs_text; continue; } if ($vb_can_handle_target) { $va_params = array('request' => $g_request, 'content' => $vs_text, 'table' => $ps_table_name, 'id' => $pa_row_ids[$vn_i], 'classname' => $ps_class, 'target' => $ps_target, 'additionalParameters' => null, 'options' => null); $va_params = $o_app_plugin_manager->hookGetAsLink($va_params); $va_links[] = $va_params['tag']; } else { switch (__CA_APP_TYPE__) { case 'PROVIDENCE': $va_links[] = ($vs_link = caEditorLink($g_request, $vs_text, $ps_class, $ps_table_name, $pa_row_ids[$vn_i])) ? $vs_link : $vs_text; break; case 'PAWTUCKET': $va_links[] = ($vs_link = caDetailLink($g_request, $vs_text, $ps_class, $ps_table_name, $pa_row_ids[$vn_i])) ? $vs_link : $vs_text; break; default: $va_links[] = $vs_text; break; } } } } return $va_links; }
/** * Export a single record using the mapping defined by this exporter and return as string * @param string $ps_exporter_code defines the exporter to use * @param int $pn_record_id Primary key of the record to export. Record type is determined by the table_num field for this exporter. * @param array $pa_options * singleRecord = Gives a signal to the export format implementation that this is a single record export. For certain formats * this might trigger different behavior, for instance the XML export format prepends the item-level output with <?xml ... ?> * in those cases. * @return string Exported record as string */ public static function exportRecord($ps_exporter_code, $pn_record_id, $pa_options = array()) { ca_data_exporters::$s_instance_cache = array(); $t_exporter = ca_data_exporters::loadExporterByCode($ps_exporter_code); if (!$t_exporter) { return false; } $va_export = array(); foreach ($t_exporter->getTopLevelItems() as $va_item) { $va_export = array_merge($va_export, $t_exporter->processExporterItem($va_item['item_id'], $t_exporter->get('table_num'), $pn_record_id, $pa_options)); } // TODO: we may wanna auto-load this switch ($t_exporter->getSetting('exporter_format')) { case 'XML': $o_export = new ExportXML(); break; case 'MARC': $o_export = new ExportMARC(); break; case 'CSV': $o_export = new ExportCSV(); break; default: return; } // if someone wants to mangle the whole tree ... well, go right ahead $o_manager = new ApplicationPluginManager(); //caDebug($va_export, "Export before tree plugin hook"); if (is_null($va_plugin_export = $o_manager->hookExportRecord(array('exporter_instance' => $t_exporter, 'record_id' => $pn_record_id, 'export' => $va_export)))) { return; // skip this record if plugin returns null } else { $va_export = $va_plugin_export['export']; } //caDebug($va_export,"Export after tree plugin hook"); $pa_options['settings'] = $t_exporter->getSettings(); return $o_export->processExport($va_export, $pa_options); }