private function CreateObject($row, RegistryManifest $registry_manifest = null) { // TODO: // Remove cross-reference to Registry $RegFactory = RegistryModuleFactory::GetInstance(); if ($row['TLD']) { $registry = $RegFactory->GetRegistryByExtension($row['TLD']); } else { $Manifest = new RegistryManifest(sprintf('%s/registries/%s/module.xml', MODULES_PATH, $row['module_name'])); $registryOptions = $Manifest->GetRegistryOptions(); if ((bool) $registryOptions->ability->section_shared_contacts) { // Contacts shared between sections. i.e. contact is suitable for all TLDs $rows = $this->DB->GetAll("SELECT tld FROM tlds WHERE modulename = ? AND isactive = 1", array($row['module_name'])); $tlds = array(); foreach ($rows as $_r) { $tlds[] = $_r['tld']; } } else { $Manifest->SetSection($row['section_name']); list($target) = $Manifest->GetSectionConfig()->xpath(sprintf("contact_groups/group[@name='%s']/targets/target[%d]", $row['groupname'], $row['target_index'] + 1)); if (!$target) { throw new ApplicationException(sprintf(_("Error in module manifest. Cannot find corresponding contact group for %s:%s"), $row['groupname'], $row['target_index'] + 1)); } $tlds = explode(',', $target->attributes()->tlds); if (!$tlds) { throw new ApplicationException(sprintf(_("Error in module manifest. Contact target tlds attribute is empty. " . "Module=%s, SectionName=%s, Index=%s"), $row["module_name"], $row["section_name"], $row['target_index'])); } // Ugly hack that helps contact to find it's configured module $in = array(); foreach ($tlds as $tld) { $in[] = "'{$tld}'"; } $tldrows = $this->DB->GetAll("SELECT TLD FROM tlds WHERE isactive=? AND modulename=? AND TLD IN (" . join(",", $in) . ")", array("1", $row['module_name'])); $tlds = array(); foreach ($tldrows as $tldrow) { $tlds[] = $tldrow["TLD"]; } } foreach ($tlds as $tld) { try { $registry = $RegFactory->GetRegistryByExtension($tld); break; } catch (Exception $e) { // TODO: // This may caught when tld going first in section is inactive. // Dirty bug itself. We must solve it Log::Log("Cannot load contact. tld={$tld} message=" . $e->getMessage(), E_USER_ERROR); } } if (!$registry) { throw new ApplicationException(sprintf(_("Cannot find registry object, that can handle contact ID=%d"), $row["id"])); } } $contact = $registry->NewContactInstanceByGroup($row['groupname']); $contact->Registry = $registry; // Map fields to properties foreach ($this->FieldPropertyMap as $field => $property) { $contact->{$property} = $row[$field]; } $disclose_data = $this->DB->GetAll('SELECT * FROM contacts_discloses WHERE contactid = ?', array($contact->CLID)); foreach ($disclose_data as $disclose_row) { $contact->SetDiscloseValue($disclose_row['field_name'], (int) $disclose_row['value']); } // Load contact fields //$contact_fields = $registry_manifest->GetContactFields($contact->Type); $contact_data = $this->DB->GetAll('SELECT * FROM contacts_data WHERE contactid = ?', array($contact->CLID)); $buf = array(); foreach ($contact_data as $contact_row) { //if (in_array($contact_row['field'], $contact_fields)) $buf[$contact_row['field']] = $contact_row['value']; } try { $contact->SetFieldList($buf, (bool) $row['strict_fields']); } catch (ErrorList $e) { Log::Log(sprintf("Strict data validation failed for contact %s. Marking this contact as non-strictly validated.", $contact->CLID), E_USER_WARNING); Log::Log(join('; ', $e->GetAllMessages()), E_USER_WARNING); $contact->SetFieldList($buf, false); } // Extra stored data is diff between raw contact fields and manifset's defined fields $contact->ExtraStoredData = array_diff_key($buf, $contact->GetFieldList()); // Add pending operations to contact $operations = $this->DB->GetAll("SELECT * FROM pending_operations WHERE objecttype='CONTACT' AND objectid=?", array($contact->ID)); foreach ($operations as $op) { $contact->AddPendingOperation($op["operation"]); } // Add contact to loaded objects storage $this->LoadedObjects[$contact->ID] = clone $contact; return $contact; }