/** * Short description of method duplicate * * @access public * @author Joel Bout, <*****@*****.**> * @param Resource resource * @param array excludedProperties * @return \core_kernel_classes_Resource */ public function duplicate(\core_kernel_classes_Resource $resource, $excludedProperties = array()) { $returnValue = null; $referencer = ResourceReferencer::singleton(); $tableName = $referencer->resourceLocation($resource); if (empty($tableName)) { return $returnValue; } //the new Uri $newUri = \common_Utils::getNewUri(); $dbWrapper = \core_kernel_classes_DbWrapper::singleton(); //duplicate the row in the main table $query = 'SELECT * FROM "' . $tableName . '" WHERE "uri" = ?'; $result = $dbWrapper->query($query, array($resource->getUri())); $rows = $result->fetchAll(); if (count($rows) > 0) { //get the columns to duplicate $columnProps = array(); for ($i = 0; $i < $result->columnCount(); $i++) { $column = $result->getColumnMeta($i); if (preg_match("/^[0-9]{2,}/", $column['name'])) { $propertyUri = HardapiUtils::getLongName($column['name']); if (!in_array($propertyUri, $excludedProperties)) { //check if the property is excluded $columnProps[$propertyUri] = $column['name']; } } } // Fetch the first result. $instanceId = $rows[0]['id']; //build the insert query $insertQuery = 'INSERT INTO "' . $tableName . '" ("uri"'; foreach ($columnProps as $column) { if (!is_string($column)) { throw new Exception('columns should be a string'); } $insertQuery .= ', "' . $column . '"'; } $insertQuery .= ') VALUES ('; $insertQuery .= "'{$newUri}'"; foreach ($columnProps as $column) { $insertQuery .= ", '" . $rows[0][$column] . "'"; } $insertQuery .= ')'; $insertResult = $dbWrapper->exec($insertQuery); if ($insertResult !== false && $instanceId > -1) { //duplicated data $duplicatedResource = new \core_kernel_classes_Resource($newUri); $referencer->referenceResource($duplicatedResource, $tableName, $resource->getTypes(), true); $duplicateInstanceId = Utils::getInstanceId($duplicatedResource); //now we duplciate the rows of the Props table //linearize the excluded properties $excludedPropertyList = ''; foreach ($excludedProperties as $excludedProperty) { $excludedPropertyList .= "'{$excludedProperty}',"; } $excludedPropertyList = substr($excludedPropertyList, 0, strlen($excludedPropertyList) - 1); //query templates of the 3 ways to insert the props rows $insertPropValueQuery = 'INSERT INTO "' . $tableName . 'props" ("property_uri", "property_value", "l_language", "instance_id") VALUES (?,?,?,?)'; $insertPropForeignQuery = 'INSERT INTO "' . $tableName . 'props" ("property_uri", "property_foreign_uri", "l_language", "instance_id") VALUES (?,?,?,?)'; $insertPropEmptyQuery = 'INSERT INTO "' . $tableName . 'props" ("property_uri", "l_language", "instance_id") VALUES (?,?,?)'; //get the rows to duplicate try { $propsQuery = 'SELECT * FROM "' . $tableName . 'props" WHERE "instance_id" = ? '; $propsQuery .= empty($excludedPropertyList) ? '' : ' AND "property_uri" NOT IN (' . $excludedPropertyList . ') '; $propsResult = $dbWrapper->query($propsQuery, array($instanceId)); } catch (\PDOException $e) { throw new Exception("Unable to duplicate the resource {$resource->getUri()} : " . $e->getMessage()); } while ($row = $propsResult->fetch()) { $propUri = $row['property_uri']; $propValue = $row['property_value']; $propForeign = $row['property_foreign_uri']; $proplang = $row['l_language']; //insert them regarding the populated columns if (!is_null($propValue) && !empty($propValue)) { $dbWrapper->exec($insertPropValueQuery, array($propUri, $propValue, $proplang, $duplicateInstanceId)); } else { if (!is_null($propForeign) && !empty($propForeign)) { $dbWrapper->exec($insertPropForeignQuery, array($propUri, $propForeign, $proplang, $duplicateInstanceId)); } else { $dbWrapper->exec($insertPropEmptyQuery, array($propUri, $proplang, $duplicateInstanceId)); //costly to insert NULL values } } } //return the duplciated resource $returnValue = $duplicatedResource; } } return $returnValue; }
/** * (non-PHPdoc) * @see core_kernel_persistence_ClassInterface::createInstanceWithProperties() */ public function createInstanceWithProperties(\core_kernel_classes_Class $type, $properties) { $returnValue = null; if (isset($properties[RDF_TYPE])) { throw new \core_kernel_persistence_Exception('Additional types in createInstanceWithProperties not permited'); } $uri = \common_Utils::getNewUri(); $table = '_' . HardapiUtils::getShortName($type); // prepare properties $hardPropertyNames = array("uri" => $uri); $dbWrapper = \core_kernel_classes_DbWrapper::singleton(); if (is_array($properties)) { if (count($properties) > 0) { // Get the table name $referencer = ResourceReferencer::singleton(); $queryProps = array(); foreach ($properties as $propertyUri => $value) { $property = new \core_kernel_classes_Property($propertyUri); $propertyLocation = $referencer->propertyLocation($property); if (in_array("{$table}props", $propertyLocation) || !$referencer->isPropertyReferenced($property)) { $propertyRange = $property->getRange(); $lang = $property->isLgDependent() ? \common_session_SessionManager::getSession()->getDataLanguage() : ''; $formatedValues = array(); if ($value instanceof \core_kernel_classes_Resource) { $formatedValues[] = $dbWrapper->quote($value->getUri()); } else { if (is_array($value)) { foreach ($value as $val) { if ($val instanceof \core_kernel_classes_Resource) { $formatedValues[] = $dbWrapper->quote($val->getUri()); } else { $formatedValues[] = $dbWrapper->quote($val); } } } else { $formatedValues[] = $dbWrapper->quote($value); } } if (is_null($propertyRange) || $propertyRange->getUri() == RDFS_LITERAL) { foreach ($formatedValues as $formatedValue) { $queryProps[] = "'{$property->getUri()}', {$formatedValue}, null, '{$lang}'"; } } else { foreach ($formatedValues as $formatedValue) { $queryProps[] = "'{$property->getUri()}', null, {$formatedValue}, '{$lang}'"; } } } else { $propertyName = HardapiUtils::getShortName($property); if (is_array($value)) { if (count($value) > 1) { throw new Exception("try setting multivalue for the non multiple property {$property->getLabel()} ({$property->getUri()})"); } else { $value = count($value) == 0 ? null : reset($value); // take the only element } } if ($value instanceof \core_kernel_classes_Resource) { $value = $value->getUri(); } $hardPropertyNames[$propertyName] = $value; } } } } // spawn $returnValue = new \core_kernel_classes_Resource($uri, __METHOD__); $varnames = '"' . implode('","', array_keys($hardPropertyNames)) . '"'; try { $query = 'INSERT INTO "' . $table . '" (' . $varnames . ') VALUES (' . implode(',', array_fill(0, count($hardPropertyNames), '?')) . ')'; $result = $dbWrapper->exec($query, array_values($hardPropertyNames)); // reference the newly created instance ResourceReferencer::singleton()->referenceResource($returnValue, $table, array($type), true); // @todo this shoould be retrievable without an aditional query $instanceId = Utils::getInstanceId($returnValue); // @todo Merge into a single query if (!empty($queryProps)) { $prefixed = array(); foreach ($queryProps as $row) { $prefixed[] = ' (' . $instanceId . ', ' . $row . ')'; } try { $query = 'INSERT INTO "' . $table . 'props" ("instance_id", "property_uri", "property_value", "property_foreign_uri", "l_language") VALUES ' . implode(',', $prefixed); $result = $dbWrapper->exec($query); } catch (\PDOException $e) { throw new Exception("Unable to set properties (multiple) Value for the instance {$returnValue->getUri()} in {$tableName} : " . $e->getMessage()); } } } catch (\PDOException $e) { throw new Exception("Unable to create instance for the class {$type->getUri()} in the table {$table} : " . $e->getMessage()); } return $returnValue; }