Example #1
0
 /**
  * Solver constructor.
  * @param Relation $relation
  * @param EntityStructure $structure
  * @param Query $query
  */
 public function __construct(&$relation, &$structure, &$query)
 {
     $this->relation =& $relation;
     $this->structure =& $structure;
     $this->query =& $query;
     // Determinate target structure
     $this->targetStructure = EntityManager::getInstance()->getEntityStructure($relation->targetEntity);
 }
Example #2
0
 /**
  * Fetch target entity or entities.
  *
  * @param Entity $entity
  * @return mixed
  */
 public function solveFetch(Entity &$entity)
 {
     // We need to find all target entities with the ID defined in the current entity source column
     $column = $this->relation->join->column;
     $value = $entity->{$column};
     $where = array($this->relation->join->targetColumn => $value);
     $query = EntityManager::find($this->relation->targetEntity);
     return $query->where($where)->all();
 }
Example #3
0
 /**
  * @covers \SweetORM\EntityManager
  * @covers \SweetORM\EntityManager::getInstance
  * @covers \SweetORM\EntityManager::isRegistered
  * @covers \SweetORM\EntityManager::registerEntity
  * @covers \SweetORM\EntityManager::getEntityStructure
  * @covers \SweetORM\Structure\EntityStructure
  * @covers \SweetORM\Structure\Indexer\TableIndexer
  * @covers \SweetORM\Structure\Indexer\EntityIndexer
  * @covers \SweetORM\Structure\Indexer\ColumnIndexer
  * @covers \SweetORM\Structure\Indexer\RelationIndexer
  */
 public function testRegisterEntity()
 {
     $manager = EntityManager::getInstance();
     $manager->clearRegisteredEntities();
     $registered = $manager->isRegistered(Post::class);
     $this->assertFalse($registered);
     $manager->registerEntity(Category::class);
     $registered = $manager->isRegistered(Category::class);
     $this->assertTrue($registered);
     $structure = $manager->getEntityStructure(Category::class);
     $this->assertInstanceOf("\\SweetORM\\Structure\\EntityStructure", $structure);
     $this->assertEquals(Category::class, $structure->name);
     $this->assertEquals("category", $structure->tableName);
 }
Example #4
0
 /**
  * Get validator and filler class for provided data.
  *
  * @param mixed $data
  * @return Structure\Validator\Validator|false
  */
 public static function validator($data)
 {
     return EntityManager::getInstance()->validator(static::class, $data);
 }
Example #5
0
 /**
  * Solve when saving, this will only be called when changes made to the relation property!
  *
  * @param Entity $entity
  * @param ArrayCollection $value
  *
  * @return mixed
  *
  * @throws \Exception
  */
 public function solveSave(Entity &$entity, &$value)
 {
     // We need to sync our collection with the jointable inbetween us.
     // We can have some deleted ones in our collection, but we are not sure.
     /** @var JoinTable $joinTable */
     $joinTable = $this->relation->join;
     // Table to sync it to.
     // First we need to verify if we got an ArrayCollection here
     if (!$value instanceof ArrayCollection) {
         throw new RelationException("Value given in your '" . $this->structure->name . "' entity relation (many to many) should always be an ArrayCollection instance!");
     }
     // Prepare to get id's from our entities!
     $currentId = $entity->_id;
     $insertIds = array();
     $ourColumn = $joinTable->column->name;
     $targetColumn = $joinTable->targetColumn->name;
     // Check if we only have an empty collection, then only delete from the joinTable
     if ($value->count() === 0) {
         // Only clear table contents (with join params)
         $delete = EntityManager::query($entity, false)->delete($joinTable->name)->where($ourColumn, $currentId)->apply();
         if ($delete === false) {
             throw new RelationException("We can not solve the Many to Many relation save! Please verify your \n                structure in PHP classes and the database for the join table. Delete problems (all delete)!");
         }
         return true;
         // Make sure we stop here, no inserts needed
     }
     // Parse all items in the collection, prepare the jointable inserts.
     foreach ($value as $item) {
         if (is_int($item)) {
             // The user already gave us an ID only! Add it anyway
             $insertIds[] = $item;
             continue;
         }
         if (!$item instanceof Entity) {
             throw new RelationException("Values given in your '" . $this->structure->name . "' entity relation \n                (many to many) should always be an ArrayCollection with inside ID's or Entities!");
         }
         if ($item->_id === null) {
             throw new RelationException("Entities given inside of your ArrayCollection for relations \n                (entity: '" . $this->structure->name . "') should always be saved or fetched, \n                current entity not saved/fetched!");
         }
         $insertIds[] = $item->_id;
     }
     // We have enough information, we need to sync the db with our ids.
     // Delete all current entries with our current id in it.
     $delete = EntityManager::query($entity, false)->delete($joinTable->name)->where($ourColumn, $currentId)->apply();
     // This could be a bit better with syncing, instead of just replacing everything (TODO).
     if ($delete === false) {
         throw new RelationException("We can not solve the Many to Many relation save! \n            Please verify your structure in PHP classes and the database for the join table. Delete problems!");
     }
     $sql = "INSERT INTO {$joinTable->name} (`{$ourColumn}`, `{$targetColumn}`) VALUES ";
     $idx = 0;
     $max = count($insertIds);
     foreach ($insertIds as $rowNum => $rowId) {
         $sql .= " (:ourid, :target_{$rowNum})";
         if ($idx + 1 < $max) {
             $sql .= ", ";
         }
         $idx++;
     }
     $statement = EntityManager::query($entity, false)->prepare($sql);
     $statement->bindValue(":ourid", $currentId);
     foreach ($insertIds as $num => $rowId) {
         $statement->bindValue(":target_{$num}", $rowId);
     }
     $insert = $statement->execute();
     if ($insert === false) {
         throw new RelationException("We can not solve the Many to Many relation save! Please verify your structure in PHP classes and the database for the join table. Insert problems! " . implode(' - ', $statement->errorInfo()));
     }
     return true;
 }
Example #6
0
 /**
  * @param EntityStructure $structure
  * @param \ReflectionProperty $property
  * @param ManyToMany|Relation $relation
  *
  * @throws RelationException Class not correct, no target property found or not extending Entity.
  * @throws \ReflectionException Class not found
  */
 private function manyToMany(&$structure, $property, $relation)
 {
     $from = $structure->name;
     $to = $relation->targetEntity;
     $reflection = null;
     try {
         $reflection = new \ReflectionClass($to);
     } catch (\Exception $e) {
         // @codeCoverageIgnore
         // Ignore, we will throw error on the next if. // @codeCoverageIgnore
     }
     if ($reflection === null || !$reflection->isSubclassOf(Entity::class)) {
         throw new RelationException("The target entity of your relation on the entity '" . $from . "' and property '" . $property->getName() . "' has an unknown target Entity!");
         // @codeCoverageIgnore
     }
     /** @var JoinTable $join */
     $join = $this->getJoin($property, JoinTable::class);
     $join->sourceEntityName = $from;
     $join->targetEntityName = $to;
     $relation->join = $join;
     // Register the join table
     EntityManager::getInstance()->registerJoinTable($join);
     // Add declaration to the structure
     $structure->relationProperties[] = $property->getName();
     $structure->foreignColumnNames[] = $join->column;
     $structure->relations[$property->getName()] = $relation;
 }
Example #7
0
 /**
  * @covers \SweetORM\EntityManager
  * @covers \SweetORM\EntityManager::getInstance
  * @covers \SweetORM\EntityManager::getEntityStructure
  * @covers \SweetORM\EntityManager::validator
  * @covers \SweetORM\Entity::validator
  * @covers \SweetORM\Structure\EntityStructure
  * @covers \SweetORM\Structure\ValidationManager
  * @covers \SweetORM\Structure\ValidationManager::validator
  * @covers \SweetORM\Structure\Validator\Validator
  * @covers \SweetORM\Structure\Validator\ArrayValidator
  * @covers \SweetORM\Structure\Annotation\Constraint
  * @covers \SweetORM\Structure\Indexer\ColumnIndexer
  * @covers \SweetORM\Database\Query
  */
 public function testConstraints()
 {
     $manager = EntityManager::getInstance();
     $manager->clearRegisteredEntities();
     $array = array('startsWith' => 'www.google.com');
     $result = ConstraintTest::validator($array)->test();
     $this->assertFalse($result->isSuccess());
     $array = array('startsWith' => 'www.google.com/testi');
     $result = ConstraintTest::validator($array)->test();
     $this->assertTrue($result->isSuccess());
     $array = array('startsWith' => 'www.google.com/testi');
     $result = ConstraintTest::validator($array)->test();
     $this->assertTrue($result->isSuccess());
     $array = array('startsWith' => 'www.google.com/testin');
     $result = ConstraintTest::validator($array)->test();
     $this->assertTrue($result->isSuccess());
     $array = array('startsWith' => 'ww.google.com/testin');
     $result = ConstraintTest::validator($array)->test();
     $this->assertFalse($result->isSuccess());
     $result = ConstraintTest::validator(array('question' => 'noo'))->test();
     $this->assertFalse($result->isSuccess());
     $result = ConstraintTest::validator(array('question' => 'YES'))->test();
     $this->assertFalse($result->isSuccess());
     $result = ConstraintTest::validator(array('question' => 'no'))->test();
     $this->assertTrue($result->isSuccess());
     $result = ConstraintTest::validator(array('question' => 'yes'))->test();
     $this->assertTrue($result->isSuccess());
     $result = ConstraintTest::validator(array('between' => 44.49))->test();
     $this->assertFalse($result->isSuccess());
     $result = ConstraintTest::validator(array('between' => 44.5))->test();
     $this->assertTrue($result->isSuccess());
     $result = ConstraintTest::validator(array('between' => 55.5))->test();
     $this->assertTrue($result->isSuccess());
     $result = ConstraintTest::validator(array('between' => 55.51))->test();
     $this->assertFalse($result->isSuccess());
     $result = ConstraintTest::validator(array('endsWith' => 'www.test.com'))->test();
     $this->assertTrue($result->isSuccess());
     $result = ConstraintTest::validator(array('endsWith' => 'www.whereisgoogle.com'))->test();
     // == 21 chars
     $this->assertFalse($result->isSuccess());
     $result = ConstraintTest::validator(array('endsWith' => 'www.hereisgoogle.com'))->test();
     // == 20 chars
     $this->assertTrue($result->isSuccess());
     $result = ConstraintTest::validator(array('endsWith' => 'www.test.nl'))->test();
     // != .com
     $this->assertFalse($result->isSuccess());
     $result = ConstraintTest::validator(array('youtube' => 'www.test.nl'))->test();
     $this->assertFalse($result->isSuccess());
     $result = ConstraintTest::validator(array('youtube' => 'https://youtu.be'))->test();
     $this->assertFalse($result->isSuccess());
     $result = ConstraintTest::validator(array('youtube' => 'https://youtu.be/dQw4w9WgXcQ'))->test();
     $this->assertTrue($result->isSuccess());
     $result = ConstraintTest::validator(array('url' => 'https://youtu.be/dQw4w9WgXcQ'))->test();
     $this->assertTrue($result->isSuccess());
     $result = ConstraintTest::validator(array('url' => 'dQw4w9WgXcQ'))->test();
     $this->assertFalse($result->isSuccess());
 }
Example #8
0
 /**
  * Set a new relationship value.
  *
  * @param string $virtualProperty
  * @param Entity|null $relationEntity
  *
  * @throws RelationException
  * @throws \Exception
  */
 public function set($virtualProperty, $relationEntity)
 {
     // Check for existing of the relation property
     if (!in_array($virtualProperty, $this->structure->relationProperties) || !isset($this->structure->relations[$virtualProperty])) {
         throw new RelationException("Relation not defined!");
         // @codeCoverageIgnore
     }
     // Make cache array if needed, for lazy loading
     if (!isset(self::$lazy[get_class($this->entity)][$virtualProperty])) {
         self::$lazy[get_class($this->entity)][$virtualProperty] = array();
     }
     /** @var Relation $relation */
     $relation = $this->structure->relations[$virtualProperty];
     if (!$relation instanceof Relation) {
         throw new RelationException("Relation indexing failed, something is really wrong, please report! Fetch proprty no instance of relation!");
         // @codeCoverageIgnore
     }
     // Can only set OneToOne and ManyToOne
     if (!$relation instanceof OneToOne && !$relation instanceof ManyToOne) {
         throw new RelationException("Only relations OneToOne and ManyToOne could be set!");
         // @codeCoverageIgnore
     }
     // If NULL then set null into the entity id column (fk)
     if ($relationEntity === null) {
         // Set null
         $this->entity->{$relation->join->column} = null;
         return;
     }
     // Get target structure
     $targetStructure = EntityManager::getInstance()->getEntityStructure($relationEntity);
     // Check if relationEntity is saved, if not throw exception!
     if (!$relationEntity->_saved) {
         throw new RelationException("Save the relationship entity first!");
     }
     // Set the id in the from entity
     $id = $relationEntity->{$targetStructure->primaryColumn->propertyName};
     $this->entity->{$relation->join->column} = $id;
     // Set the cache
     self::$lazy[get_class($this->entity)][$virtualProperty][$id] = $relationEntity;
 }