public function testCreateInstanceHardified()
 {
     $rr = ResourceReferencer::singleton();
     $this->assertFalse($rr->isClassReferenced($this->class));
     $softinstance = core_kernel_classes_ResourceFactory::create($this->class);
     $this->assertFalse($rr->isResourceReferenced($softinstance));
     $switcher = new Switcher();
     $switcher->hardify($this->class, array('topclass' => $this->class));
     unset($switcher);
     $this->assertTrue($rr->isClassReferenced($this->class));
     common_Logger::i('creating hardified');
     $hardinstance = core_kernel_classes_ResourceFactory::create($this->class);
     $this->assertTrue($rr->isResourceReferenced($hardinstance), 'Instance created from harmode class was added in softmode');
     $softinstance->delete();
     $hardinstance->delete();
     $switcher = new Switcher();
     $switcher->unhardify($this->class);
     unset($switcher);
 }
 /**
  * Short description of method isValidContext
  *
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param  Resource resource
  * @return boolean
  */
 public function isValidContext(\core_kernel_classes_Resource $resource)
 {
     $returnValue = (bool) false;
     if (ResourceReferencer::singleton()->isResourceReferenced($resource)) {
         $returnValue = true;
     }
     return (bool) $returnValue;
 }
 public function propertyDescriptor(\core_kernel_classes_Property $property, $hardRangeClassOnly = false)
 {
     $returnValue = array('name' => Utils::getShortName($property), 'isMultiple' => $property->isMultiple(), 'isLgDependent' => $property->isLgDependent(), 'range' => array());
     $range = $property->getRange();
     $rangeClassName = Utils::getShortName($range);
     if ($hardRangeClassOnly) {
         if (ResourceReferencer::singleton()->isClassReferenced($range)) {
             $returnValue[] = $rangeClassName;
         }
     } else {
         $returnValue[] = $rangeClassName;
     }
     return (array) $returnValue;
 }
 /**
  * Will create an Index (in the RDBMS) for all the promperties passed as
  * a parameter. This may increase the performance of the system.
  * 
  * @static
  * @access public
  * @param array $indexProperties
  * @throws Exception
  * @return boolean If it succeeds, false otherwise.
  */
 public static function createIndex($indexProperties = array())
 {
     $referencer = ResourceReferencer::singleton();
     $dbWrapper = \core_kernel_classes_DbWrapper::singleton();
     foreach ($indexProperties as $indexProperty) {
         $property = new \core_kernel_classes_Property($indexProperty);
         $propertyAlias = Utils::getShortName($property);
         foreach ($referencer->propertyLocation($property) as $table) {
             if (!preg_match("/props\$/", $table) && preg_match("/^_[0-9]{2,}/", $table)) {
                 try {
                     $indexName = 'idx_' . $table . '_' . $propertyAlias;
                     if (strlen($indexName) > 64) {
                         $md5 = md5($indexName);
                         $indexName = substr($indexName, 0, 30) . $md5;
                     }
                     $dbWrapper->createIndex($indexName, $dbWrapper->quoteIdentifier($table), array($dbWrapper->quoteIdentifier($propertyAlias) => 255));
                 } catch (\Exception $e) {
                     if ($e->getCode() != $dbWrapper->getIndexAlreadyExistsErrorCode() && $e->getCode() != '00000') {
                         throw new Exception("Unable to create index 'idx_{$propertyAlias}' for property alias '{$propertyAlias}' on table '{$table}': {$e->getMessage()}");
                     } else {
                         \common_Logger::e('something go wrong when creating index idx_' . $propertyAlias . ' on table ' . $table . ' : ' . $e->getMessage());
                     }
                 }
             }
         }
     }
     return true;
 }
 /**
  * Test the referencer on properties, using the file caching mode
  * (it's the default caching mode for the properties)
  * @see oat\generisHard\models\hardapi\ResourceReferencer
  */
 public function testPropertyReferencer()
 {
     $referencer = ResourceReferencer::singleton();
     $this->assertIsA($referencer, 'oat\\generisHard\\models\\hardapi\\ResourceReferencer');
     $referencer->setPropertyCache(ResourceReferencer::CACHE_FILE);
     $referencer->clearCaches();
     $class = new core_kernel_classes_Class(CLASS_GENERIS_USER);
     $table = '_' . Utils::getShortName($class);
     // this part simulates a hardifying of the Userclass
     $myUserTblMgr = new TableManager($table);
     $this->assertFalse($myUserTblMgr->exists());
     $this->assertTrue($myUserTblMgr->create(array(array('name' => '05label'), array('name' => '05comment'), array('name' => '07login'), array('name' => '07password'), array('name' => '07userMail'), array('name' => '07userFirstName'), array('name' => '07userLastName'))));
     $this->assertTrue($myUserTblMgr->exists());
     $referencer->referenceClass($class);
     $this->assertTrue($referencer->isClassReferenced($class));
     // test start on the cache containing the simulated data
     // in case of a  fallback to the real sata (class_to_table) the tests fail
     $labelProperty = new core_kernel_classes_Property(RDFS_LABEL);
     $this->assertTrue($referencer->isPropertyReferenced($labelProperty));
     $commentProperty = new core_kernel_classes_Property(RDFS_COMMENT);
     $this->assertTrue($referencer->isPropertyReferenced($commentProperty));
     $loginProperty = new core_kernel_classes_Property(PROPERTY_USER_LOGIN);
     $this->assertTrue($referencer->isPropertyReferenced($loginProperty));
     $passwordProperty = new core_kernel_classes_Property(PROPERTY_USER_PASSWORD);
     $this->assertTrue($referencer->isPropertyReferenced($passwordProperty));
     $firstNameProperty = new core_kernel_classes_Property(PROPERTY_USER_FIRSTNAME);
     foreach ($referencer->propertyLocation($firstNameProperty) as $foundTable) {
         $this->assertEquals($foundTable, $table);
     }
     $this->assertTrue($myUserTblMgr->exists());
     $referencer->unReferenceClass($class);
     $this->assertFalse($referencer->isClassReferenced($class));
     $this->assertFalse($myUserTblMgr->exists());
     // Testing the cache...
     $cache = common_cache_FileCache::singleton();
     $serial = 'hard-api-property';
     $this->assertTrue($cache->has($serial));
     try {
         $cacheContent = $cache->get($serial);
         $this->assertTrue(is_array($cacheContent));
         $this->assertTrue(count($cacheContent) > 0);
         $this->assertTrue(array_key_exists(RDFS_LABEL, $cacheContent));
         $this->assertTrue(array_key_exists(PROPERTY_USER_LOGIN, $cacheContent));
     } catch (common_cache_Exception $e) {
         $this->fail('Cannot access hard-api-property cache.');
     }
     //clear the cache
     $cache->remove($serial);
     $this->assertFalse($cache->has($serial));
 }
 /**
  * Returns the list of optimizable classes. The classes that are optimizable are found
  * in the manifests of extensions that are currently installed.
  *
  * + The returned associative array has key values corresponding to a Class URI, and the values
  * are the optimization options that have to be used in order to optimize classes.
  *
  * + The optimization options are associative arrays containing boolean values depicting how
  * the class must be optmized. The following keys are provided:
  *
  *  - compile: array('recursive' =>          true/false,
  *                   'append' =>              true/false,
  *                   'rmSources' =>           true/false)
  *
  *  - decompile: array('recursive' =>        true/false)
  *
  * + The status of classes (compiled or decompiled) are described in the 'status' key.
  *
  *  - status: string	'compiled'/'decompiled
  *
  * + The amount of already compiled/decompiled instances of classes are described in the 'count' key.
  *
  *  - count: integer
  *
  * + The class name of classes are described in the 'class' key:
  *
  *  - class: string		(e.g. 'User', 'Item', ...)
  *
  * + The class URI of classes are described in the 'classUri' key:
  *
  * - classUri: string	(e.g. 'http://myplatform/mytao.rdf#user1', ...)
  *
  * @return array The Optimizable classes, their optimization options and miscellaneous information.
  */
 public static function getOptimizableClasses()
 {
     $returnValue = array();
     $optionsCompile = array('recursive' => true, 'append' => true, 'rmSources' => true);
     $optionsDecompile = array('recursive' => true);
     $defaultOptions = array('compile' => $optionsCompile, 'decompile' => $optionsDecompile);
     $optimizableClasses = array();
     $extManager = \common_ext_ExtensionsManager::singleton();
     $extensions = $extManager->getInstalledExtensions();
     foreach ($extensions as $ext) {
         $optimizableClasses = array_merge($optimizableClasses, $ext->getOptimizableClasses());
     }
     $optimizableClasses = array_unique($optimizableClasses);
     $referencer = ResourceReferencer::singleton();
     foreach ($optimizableClasses as $optClass) {
         $optClass = new \core_kernel_classes_Class($optClass);
         $values['compile'] = $defaultOptions['compile'];
         $values['decompile'] = $defaultOptions['decompile'];
         $values['count'] = self::getClassInstancesCount($optClass);
         $values['class'] = $optClass->getLabel();
         $values['classUri'] = $optClass->getUri();
         $values['status'] = $referencer->isClassReferenced($optClass) ? self::COMPILED : self::DECOMPILED;
         $returnValue[$optClass->getUri()] = $values;
     }
     return $returnValue;
 }
 /**
  * Change a multi-valued property to a single-valued one.
  *
  * @access public
  * @author Jerome Bogaerts, <*****@*****.**>
  * @param  Resource property The property to modifiy.
  * @param  int batchSize Data must be transfered from the properties table to a given column. This parameter indicates the size of each pack of data transfered from the properties table to the column.
  * @return void
  */
 public static function multipleToScalar(\core_kernel_classes_Resource $property, $batchSize = 100)
 {
     $referencer = ResourceReferencer::singleton();
     $dbWrapper = \core_kernel_classes_DbWrapper::singleton();
     $propertyDescription = self::propertyDescriptor($property);
     $propertyLocations = $referencer->propertyLocation($property);
     $propName = $propertyDescription['name'];
     $propUri = $property->getUri();
     $propRanges = array();
     foreach ($propertyDescription['range'] as $range) {
         // If no range provided, we assume it is a Literal.
         $propRanges[] = !empty($range) ? $range->getUri() : RDFS_LITERAL;
     }
     $offset = 0;
     foreach ($propertyLocations as $tblname) {
         $tblmgr = new TableManager($tblname);
         if ($tblmgr->exists()) {
             // Reset offset.
             $offset = 0;
             try {
                 // We go from multiple to single.
                 $toDelete = array();
                 // will contain ids of rows to delete in the 'properties table' after data transfer.
                 // Add a column to the base table to receive single value.
                 $baseTableName = str_replace('props', '', $tblname);
                 $tblmgr->setName($baseTableName);
                 $shortName = self::getShortName($property);
                 $columnAdded = $tblmgr->addColumn(array('name' => $shortName, 'multi' => false));
                 if ($columnAdded == true) {
                     // Now get the values in the props table. Group by instance ID in order to get only
                     // one value to put in the target column.
                     do {
                         $hasResult = false;
                         $retrievePropertyValue = empty($propRanges) || in_array(RDFS_LITERAL, $propRanges) ? true : false;
                         $sql = 'SELECT "a"."id", "a"."instance_id", "a"."property_value", "a"."property_foreign_uri" FROM "' . $tblname . '" "a" ';
                         $sql .= 'RIGHT JOIN (SELECT "instance_id", MIN("id") AS "id" FROM "' . $tblname . '" WHERE "property_uri" = ? ';
                         $sql .= 'GROUP BY "instance_id") AS "b" ON ("a"."id" = "b"."id")';
                         $sql = $dbWrapper->limitStatement($sql, $batchSize, $offset);
                         $result = $dbWrapper->query($sql, array($propUri));
                         // prepare the update statement.
                         $sql = 'UPDATE "' . $baseTableName . '" SET "' . $shortName . '" = ? WHERE "id" = ?';
                         while ($row = $result->fetch()) {
                             // Transfer to the 'base table'.
                             $hasResult = true;
                             $propertyValue = $retrievePropertyValue == true ? $row['property_value'] : $row['property_foreign_uri'];
                             $dbWrapper->exec($sql, array($propertyValue, $row['instance_id']));
                             $toDelete[] = $row['id'];
                         }
                         $offset += $batchSize;
                     } while ($hasResult === true);
                     $inData = implode(',', $toDelete);
                     $sql = 'DELETE FROM "' . $tblname . '" WHERE "id" IN (' . $inData . ')';
                     if ($dbWrapper->exec($sql) == 0) {
                         // If an error occured or no rows removed, we
                         // have a problem.
                         $msg = "Cannot set multiplicity of Property '{$propUri}' because data transfered to the 'base table' could not be deleted";
                         throw new Exception($msg);
                     }
                 } else {
                     $msg = "Cannot set multiplicity of Property '{$propUri}' because the corresponding 'base table' column could not be created.";
                     throw new Exception($msg);
                 }
             } catch (\PDOException $e) {
                 $msg = "Cannot set multiplicity of Property '{$propUri}': " . $e->getMessage();
                 throw new Exception($msg);
             }
         } else {
             $msg = "Cannot set multiplicity of Property '{$propUri}' because the corresponding database location '{$tblname}' does not exist.";
             throw new Exception($msg);
         }
     }
     $referencer->clearCaches();
 }
 public function testHardPropertyModifications()
 {
     $this->hardify();
     $this->createData();
     $dbWrapper = core_kernel_classes_DbWrapper::singleton();
     $movieClass = $this->targetMovieClass;
     $workClass = $this->targetWorkClass;
     $authorProperty = $this->targetAuthorProperty;
     $producerProperty = $this->targetProducerProperty;
     $actorsProperty = $this->targetActorsProperty;
     $labelProperty = new core_kernel_classes_Property(RDFS_LABEL);
     $referencer = ResourceReferencer::singleton();
     $propertyProxy = PropertyProxy::singleton();
     // Retrieve interesting resources.
     $instances = $workClass->searchInstances(array($authorProperty->getUri() => 'Leonardo da Vinci'), array('like' => false, 'recursive' => false));
     $monaLisa = current($instances);
     $instances = $movieClass->searchInstances(array($labelProperty->getUri() => 'The Lord of the Rings'), array('like' => false, 'recursive' => false));
     $lordOfTheRings = current($instances);
     $instances = $movieClass->searchInstances(array($labelProperty->getUri() => 'The Hobbit'), array('like' => true, 'recursive' => false));
     $theHobbit = current($instances);
     if (empty($monaLisa) || empty($lordOfTheRings) || empty($theHobbit)) {
         $this->fail("Unable to retrieve instances that will be used in the following tests.");
     } else {
         // Try to create a new scalar property after hardification.
         $testProperty = $movieClass->createProperty('after hardify property');
         $testPropertyShortName = Utils::getShortName($testProperty);
         $testPropertyLocations = $referencer->propertyLocation($testProperty);
         $movieClassLocations = $referencer->classLocations($movieClass);
         $movieClassTable = $movieClassLocations[0]['table'];
         $movieClassTableColumns = array();
         foreach ($dbWrapper->getColumnNames($movieClassTable) as $col) {
             $movieClassTableColumns[] = $col->getName();
         }
         $workClassLocations = $referencer->classLocations($workClass);
         $workClassTable = $movieClassLocations[0]['table'];
         $workClassTableColumns = $dbWrapper->getColumnNames($workClassTable);
         $testPropertyShortName = Utils::getShortName($testProperty);
         $authorPropertyShortName = Utils::getShortName($authorProperty);
         // test delegation and presence of the column.
         $this->assertFalse($testProperty->isMultiple());
         $this->assertTrue(in_array($testPropertyShortName, $movieClassTableColumns));
         $this->assertIsA($propertyProxy->getImpToDelegateTo($testProperty), 'oat\\generisHard\\models\\hardsql\\Property');
         // set language dependency of the test property to true.
         $testProperty->setLgDependent(true);
         $this->assertTrue($testProperty->isLgDependent());
         $movieClassTableColumns = array();
         foreach ($dbWrapper->getColumnNames($movieClassTable) as $col) {
             $movieClassTableColumns[] = $col->getName();
         }
         $this->assertFalse(in_array($testPropertyShortName, $movieClassTableColumns));
         // create some property values for the test property.
         $testMovie = $movieClass->createInstance('A Test Movie');
         $testMovie->setPropertyValue($testProperty, 'EN-TestPropertyValue-1');
         $testMovie->setPropertyValueByLg($testProperty, 'EN-TestPropertyValue-2', DEFAULT_LANG);
         $testMovie->setPropertyValueByLg($testProperty, 'FR-TestPropertyValue-1', 'FR');
         $testPropertyValues = $testMovie->getPropertyValues($testProperty);
         $this->assertEquals(count($testPropertyValues), 2);
         // Only EN values will come back.
         $testPropertyValues = $testMovie->getPropertyValuesByLg($testProperty, DEFAULT_LANG);
         $this->assertEquals(count($testPropertyValues->sequence), 2);
         $testPropertyValues = $testMovie->getPropertyValuesByLg($testProperty, 'FR');
         $this->assertEquals(count($testPropertyValues->sequence), 1);
         // set back the language dependency of the test property to false.
         $testProperty->setLgDependent(false);
         $this->assertFalse($testProperty->isLgDependent());
         $movieClassTableColumns = array();
         foreach ($dbWrapper->getColumnNames($movieClassTable) as $col) {
             $movieClassTableColumns[] = $col->getName();
         }
         $this->assertTrue(in_array($testPropertyShortName, $movieClassTableColumns));
         $testPropertyValues = $testMovie->getPropertyValues($testProperty);
         $this->assertEquals(count($testPropertyValues), 1);
         // set the author property to multiple.
         $this->assertTrue(in_array($authorPropertyShortName, $movieClassTableColumns));
         $this->assertFalse($authorProperty->isMultiple());
         $authorProperty->setMultiple(true);
         $this->assertTrue($authorProperty->isMultiple());
         $movieClassTableColumns = array();
         foreach ($dbWrapper->getColumnNames($movieClassTable) as $col) {
             $movieClassTableColumns[] = $col->getName();
         }
         $this->assertFalse(in_array($authorPropertyShortName, $movieClassTableColumns));
         // Add a fake value to make it multi valued
         $theHobbit->setPropertyValue($authorProperty, 'The Clone of Peter Jackson');
         $authors = $theHobbit->getPropertyValues($authorProperty);
         $this->assertEquals(count($authors), 2);
         $this->assertEquals(current($authors), 'Peter Jackson');
         next($authors);
         $this->assertEquals(current($authors), 'The Clone of Peter Jackson');
         $authors = $monaLisa->getPropertyValues($authorProperty);
         $this->assertEquals(count($authors), 1);
         $this->assertEquals(current($authors), 'Leonardo da Vinci');
         // reset the author property to scalar.
         $authorProperty->setMultiple(false);
         $this->assertFalse($authorProperty->isMultiple());
         $movieClassTableColumns = array();
         foreach ($dbWrapper->getColumnNames($movieClassTable) as $col) {
             $movieClassTableColumns[] = $col->getName();
         }
         $this->assertTrue(in_array($authorPropertyShortName, $movieClassTableColumns));
         $authors = $theHobbit->getPropertyValues($authorProperty);
         $this->assertEquals(count($authors), 1);
         $this->assertEquals(current($authors), 'Peter Jackson');
     }
 }
 /**
  * Short description of method getClassId
  *
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param  Class class
  * @param  Resource resource
  * @return string
  */
 public static function getClassId(\core_kernel_classes_Class $class, \core_kernel_classes_Resource $resource)
 {
     $returnValue = (string) '';
     try {
         $dbWrapper = \core_kernel_classes_DbWrapper::singleton();
         $query = 'SELECT "id" FROM "class_to_table" WHERE "uri"=? AND "table"=?';
         $result = $dbWrapper->query($query, array($class->getUri(), ResourceReferencer::singleton()->resourceLocation($resource)));
         if ($row = $result->fetch()) {
             $returnValue = $row['id'];
         }
     } catch (\PDOException $e) {
         throw new Exception("Unable to find the class {$class->getUri()} in class_to_table : " . $e->getMessage());
     }
     return (string) $returnValue;
 }
 /**
  * Short description of method isValidContext
  *
  * @access public
  * @author Jerome Bogaerts, <*****@*****.**>
  * @param  Resource resource
  * @return boolean
  */
 public function isValidContext(\core_kernel_classes_Resource $resource)
 {
     $returnValue = (bool) false;
     $returnValue = ResourceReferencer::singleton()->isPropertyReferenced($resource);
     return (bool) $returnValue;
 }
 public function testSearchInstancesVeryHard($hard = true)
 {
     if (!$hard) {
         return;
     }
     $class = new core_kernel_classes_Class('http://www.tao.lu/Ontologies/TAOSubject.rdf#Subject');
     if (ResourceReferencer::singleton()->isClassReferenced($class)) {
         //test simple search:
         $propertyFilter = array('http://www.tao.lu/Ontologies/generis.rdf#login' => 's1', 'http://www.tao.lu/Ontologies/generis.rdf#password' => 'e10adc3949ba59abbe56e057f20f883e');
         $options = array('like' => false, 'recursive' => 0);
         $languagesDependantProp = $class->searchInstances($propertyFilter, $options);
         $nfound = count($languagesDependantProp);
         $this->assertTrue($nfound > 0);
         //test like option
         $propertyFilter = array('http://www.tao.lu/Ontologies/generis.rdf#login' => '%s1', 'http://www.tao.lu/Ontologies/generis.rdf#password' => 'e10adc3949ba59abbe56e057f20f883e');
         $options = array('like' => true, 'recursive' => 0);
         $languagesDependantProp = $class->searchInstances($propertyFilter, $options);
         $likeFound = count($languagesDependantProp);
         $this->assertTrue($likeFound > 0);
         $this->assertEquals($nfound, $likeFound);
         //test reference resource prop value:
         $propertyFilter = array('http://www.tao.lu/Ontologies/generis.rdf#login' => '%s1', 'http://www.tao.lu/Ontologies/generis.rdf#password' => 'e10adc3949ba59abbe56e057f20f883e', 'http://www.tao.lu/Ontologies/generis.rdf#userDefLg' => '%FR%');
         $options = array('like' => true, 'recursive' => false);
         //test language filter (property 'http://www.tao.lu/Ontologies/generis.rdf#userDefLg' must be set to language dependent first!):
         // $options['lang'] = 'EN';
         $languagesDependantProp = $class->searchInstances($propertyFilter, $options);
         $refFound = count($languagesDependantProp);
         $this->assertTrue($refFound > 0);
         $this->assertEquals($nfound, $refFound);
     }
 }