예제 #1
0
 /**
  * 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;
 }
예제 #2
0
 /**
  * (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;
 }