Manages simple bean associations.
Author: Gabor de Mooij and the RedBeanPHP Community
Inheritance: extends redbeanphp\Observable
Beispiel #1
0
 /**
  * Test integration with pre-existing schemas.
  *
  * @return void
  */
 public function testPlaysNiceWithPreExitsingSchema()
 {
     $toolbox = R::getToolBox();
     $adapter = $toolbox->getDatabaseAdapter();
     $writer = $toolbox->getWriter();
     $redbean = $toolbox->getRedBean();
     $pdo = $adapter->getDatabase();
     $a = new AssociationManager($toolbox);
     $page = $redbean->dispense("page");
     $page->name = "John's page";
     $idpage = $redbean->store($page);
     $page2 = $redbean->dispense("page");
     $page2->name = "John's second page";
     $idpage2 = $redbean->store($page2);
     $a->associate($page, $page2);
     $adapter->exec("ALTER TABLE " . $writer->esc('page') . "\n\t\tCHANGE " . $writer->esc('name') . " " . $writer->esc('name') . "\n\t\tVARCHAR( 254 ) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL ");
     $page = $redbean->dispense("page");
     $page->name = "Just Another Page In a Table";
     $cols = $writer->getColumns("page");
     asrt($cols["name"], "varchar(254)");
     //$pdo->SethMode(1);
     $redbean->store($page);
     pass();
     // No crash?
     $cols = $writer->getColumns("page");
     asrt($cols["name"], "varchar(254)");
     //must still be same
 }
Beispiel #2
0
 /**
  * MySQL specific tests.
  *
  * @return void
  */
 public function testMySQL()
 {
     if ($this->currentlyActiveDriverID !== 'mysql') {
         return;
     }
     testpack('Throw exception in case of issue with assoc constraint');
     $bunny = R::dispense('bunny');
     $carrot = R::dispense('carrot');
     $faultyWriter = new \FaultyWriter(R::getToolBox()->getDatabaseAdapter());
     $faultyOODB = new OODB($faultyWriter);
     $faultyOODB->setBeanHelper(R::getRedBean()->getBeanHelper());
     $faultyToolbox = new ToolBox($faultyOODB, R::getToolBox()->getDatabaseAdapter(), $faultyWriter);
     $faultyAssociationManager = new AssociationManager($faultyToolbox);
     $faultyWriter->setSQLState('23000');
     $faultyAssociationManager->associate($bunny, $carrot);
     pass();
     $faultyWriter->setSQLState('42S22');
     R::nuke();
     try {
         $faultyAssociationManager->associate($bunny, $carrot);
         fail();
     } catch (SQL $exception) {
         pass();
     }
 }
Beispiel #3
0
 /**
  * Adds tags to a bean.
  * If $tagList is a comma separated list of tags all tags will
  * be associated with the bean.
  * You may also pass an array instead of a string.
  * 
  * Tag list can be either an array with tag names or a comma separated list
  * of tag names.
  *
  * @param OODBBean $bean    bean to add tags to
  * @param array|string     $tagList list of tags to add to bean
  *
  * @return void
  */
 public function addTags(OODBBean $bean, $tagList)
 {
     $tags = $this->extractTagsIfNeeded($tagList);
     if ($tagList === FALSE) {
         return;
     }
     foreach ($tags as $tag) {
         if (!($t = $this->findTagByTitle($tag))) {
             $t = $this->redbean->dispense('tag');
             $t->title = $tag;
             $this->redbean->store($t);
         }
         $this->associationManager->associate($bean, $t);
     }
 }
Beispiel #4
0
 /**
  * Configures the facade, want to have a new Writer? A new Object Database or a new
  * Adapter and you want it on-the-fly? Use this method to hot-swap your facade with a new
  * toolbox.
  *
  * @param ToolBox $tb toolbox
  *
  * @return ToolBox
  */
 public static function configureFacadeWithToolbox(ToolBox $tb)
 {
     $oldTools = self::$toolbox;
     self::$toolbox = $tb;
     self::$writer = self::$toolbox->getWriter();
     self::$adapter = self::$toolbox->getDatabaseAdapter();
     self::$redbean = self::$toolbox->getRedBean();
     self::$finder = new Finder(self::$toolbox);
     self::$associationManager = new AssociationManager(self::$toolbox);
     self::$redbean->setAssociationManager(self::$associationManager);
     self::$labelMaker = new LabelMaker(self::$toolbox);
     $helper = new SimpleModelHelper();
     $helper->attachEventListeners(self::$redbean);
     self::$redbean->setBeanHelper(new SimpleFacadeBeanHelper());
     self::$associationManager->addEventListener('delete', $helper);
     self::$duplicationManager = new DuplicationManager(self::$toolbox);
     self::$tagManager = new TagManager(self::$toolbox);
     return $oldTools;
 }
Beispiel #5
0
 /**
  * Test various.
  * Test various somewhat uncommon trash/unassociate scenarios.
  * (i.e. unassociate unrelated beans, trash non-persistant beans etc).
  * Should be handled gracefully - no output checking.
  *
  * @return void
  */
 public function testVaria2()
 {
     $toolbox = R::getToolBox();
     $redbean = $toolbox->getRedBean();
     $a = new AssociationManager($toolbox);
     $book = $redbean->dispense("book");
     $author1 = $redbean->dispense("author");
     $author2 = $redbean->dispense("author");
     $book->title = "My First Post";
     $author1->name = "Derek";
     $author2->name = "Whoever";
     $a->unassociate($book, $author1);
     $a->unassociate($book, $author2);
     pass();
     $redbean->trash($redbean->dispense("bla"));
     pass();
     $bean = $redbean->dispense("bla");
     $bean->name = 1;
     $bean->id = 2;
     $redbean->trash($bean);
     pass();
 }
Beispiel #6
0
 /**
  * (FALSE should be stored as 0 not as '')
  *
  * @return voids
  */
 public function testZeroIssue()
 {
     testpack("Zero issue");
     $toolbox = R::getToolBox();
     $redbean = $toolbox->getRedBean();
     $adapter = $toolbox->getDatabaseAdapter();
     $writer = $toolbox->getWriter();
     $pdo = $adapter->getDatabase();
     $pdo->Execute("DROP TABLE IF EXISTS `zero`");
     $bean = $redbean->dispense("zero");
     $bean->zero = FALSE;
     $bean->title = "bla";
     $redbean->store($bean);
     asrt(count($redbean->find("zero", array(), " zero = 0 ")), 1);
     R::store(R::dispense('hack'));
     testpack("Test RedBean Security - bean interface ");
     asrt(in_array("hack", $adapter->getCol("show tables")), TRUE);
     $bean = $redbean->load("page", "13; drop table hack");
     asrt(in_array("hack", $adapter->getCol("show tables")), TRUE);
     try {
         $bean = $redbean->load("page where 1; drop table hack", 1);
     } catch (\Exception $e) {
     }
     asrt(in_array("hack", $adapter->getCol("show tables")), TRUE);
     $bean = $redbean->dispense("page");
     $evil = "; drop table hack";
     $bean->id = $evil;
     try {
         $redbean->store($bean);
     } catch (\Exception $e) {
     }
     asrt(in_array("hack", $adapter->getCol("show tables")), TRUE);
     unset($bean->id);
     $bean->name = "\"" . $evil;
     try {
         $redbean->store($bean);
     } catch (\Exception $e) {
     }
     asrt(in_array("hack", $adapter->getCol("show tables")), TRUE);
     $bean->name = "'" . $evil;
     try {
         $redbean->store($bean);
     } catch (\Exception $e) {
     }
     asrt(in_array("hack", $adapter->getCol("show tables")), TRUE);
     $bean->{$evil} = 1;
     try {
         $redbean->store($bean);
     } catch (\Exception $e) {
     }
     asrt(in_array("hack", $adapter->getCol("show tables")), TRUE);
     unset($bean->{$evil});
     $bean->id = 1;
     $bean->name = "\"" . $evil;
     try {
         $redbean->store($bean);
     } catch (\Exception $e) {
     }
     asrt(in_array("hack", $adapter->getCol("show tables")), TRUE);
     $bean->name = "'" . $evil;
     try {
         $redbean->store($bean);
     } catch (\Exception $e) {
     }
     asrt(in_array("hack", $adapter->getCol("show tables")), TRUE);
     $bean->{$evil} = 1;
     try {
         $redbean->store($bean);
     } catch (\Exception $e) {
     }
     asrt(in_array("hack", $adapter->getCol("show tables")), TRUE);
     try {
         $redbean->trash($bean);
     } catch (\Exception $e) {
     }
     asrt(in_array("hack", $adapter->getCol("show tables")), TRUE);
     try {
         $redbean->find("::", array(), "");
     } catch (\Exception $e) {
         pass();
     }
     $adapter->exec("drop table if exists sometable");
     testpack("Test RedBean Security - query writer");
     try {
         $writer->createTable("sometable` ( `id` INT( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT , PRIMARY KEY ( `id` ) ) ENGINE = InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ; drop table hack; --");
     } catch (\Exception $e) {
     }
     asrt(in_array("hack", $adapter->getCol("show tables")), TRUE);
     testpack("Test ANSI92 issue in clearrelations");
     $pdo->Execute("DROP TABLE IF EXISTS book_group");
     $pdo->Execute("DROP TABLE IF EXISTS author_book");
     $pdo->Execute("DROP TABLE IF EXISTS book");
     $pdo->Execute("DROP TABLE IF EXISTS author");
     $redbean = $toolbox->getRedBean();
     $a = new AssociationManager($toolbox);
     $book = $redbean->dispense("book");
     $author1 = $redbean->dispense("author");
     $author2 = $redbean->dispense("author");
     $book->title = "My First Post";
     $author1->name = "Derek";
     $author2->name = "Whoever";
     set1toNAssoc($a, $book, $author1);
     set1toNAssoc($a, $book, $author2);
     pass();
     $pdo->Execute("DROP TABLE IF EXISTS book_group");
     $pdo->Execute("DROP TABLE IF EXISTS book_author");
     $pdo->Execute("DROP TABLE IF EXISTS author_book");
     $pdo->Execute("DROP TABLE IF EXISTS book");
     $pdo->Execute("DROP TABLE IF EXISTS author");
     $redbean = $toolbox->getRedBean();
     $a = new AssociationManager($toolbox);
     $book = $redbean->dispense("book");
     $author1 = $redbean->dispense("author");
     $author2 = $redbean->dispense("author");
     $book->title = "My First Post";
     $author1->name = "Derek";
     $author2->name = "Whoever";
     $a->associate($book, $author1);
     $a->associate($book, $author2);
     pass();
     testpack("Test Association Issue Group keyword (Issues 9 and 10)");
     $pdo->Execute("DROP TABLE IF EXISTS `book_group`");
     $pdo->Execute("DROP TABLE IF EXISTS `group`");
     $group = $redbean->dispense("group");
     $group->name = "mygroup";
     $redbean->store($group);
     try {
         $a->associate($group, $book);
         pass();
     } catch (SQL $e) {
         fail();
     }
     // Test issue SQL error 23000
     try {
         $a->associate($group, $book);
         pass();
     } catch (SQL $e) {
         fail();
     }
     asrt((int) $adapter->getCell("select count(*) from book_group"), 1);
     //just 1 rec!
     $pdo->Execute("DROP TABLE IF EXISTS book_group");
     $pdo->Execute("DROP TABLE IF EXISTS author_book");
     $pdo->Execute("DROP TABLE IF EXISTS book");
     $pdo->Execute("DROP TABLE IF EXISTS author");
     $redbean = $toolbox->getRedBean();
     $a = new AssociationManager($toolbox);
     $book = $redbean->dispense("book");
     $author1 = $redbean->dispense("author");
     $author2 = $redbean->dispense("author");
     $book->title = "My First Post";
     $author1->name = "Derek";
     $author2->name = "Whoever";
     $a->unassociate($book, $author1);
     $a->unassociate($book, $author2);
     pass();
     $redbean->trash($redbean->dispense("bla"));
     pass();
     $bean = $redbean->dispense("bla");
     $bean->name = 1;
     $bean->id = 2;
     $redbean->trash($bean);
     pass();
 }
Beispiel #7
0
 /**
  * Unassociates the list items in the trashcan.
  *
  * @param OODBBean $bean           bean
  * @param array            $sharedTrashcan list
  *
  * @return void
  */
 private function processSharedTrashcan($bean, $sharedTrashcan)
 {
     foreach ($sharedTrashcan as $trash) {
         $this->assocManager->unassociate($trash, $bean);
     }
 }
Beispiel #8
0
 /**
  * Begin testing.
  * This method runs the actual test pack.
  *
  * @return void
  */
 public function testFinding()
 {
     $toolbox = R::getToolBox();
     $adapter = $toolbox->getDatabaseAdapter();
     $writer = $toolbox->getWriter();
     $redbean = $toolbox->getRedBean();
     $pdo = $adapter->getDatabase();
     $a = new AssociationManager($toolbox);
     $page = $redbean->dispense("page");
     $page->name = "John's page";
     $idpage = $redbean->store($page);
     $page2 = $redbean->dispense("page");
     $page2->name = "John's second page";
     $idpage2 = $redbean->store($page2);
     $a->associate($page, $page2);
     $pageOne = $redbean->dispense("page");
     $pageOne->name = "one";
     $pageMore = $redbean->dispense("page");
     $pageMore->name = "more";
     $pageEvenMore = $redbean->dispense("page");
     $pageEvenMore->name = "evenmore";
     $pageOther = $redbean->dispense("page");
     $pageOther->name = "othermore";
     set1toNAssoc($a, $pageOther, $pageMore);
     set1toNAssoc($a, $pageOne, $pageMore);
     set1toNAssoc($a, $pageOne, $pageEvenMore);
     asrt(count($redbean->find("page", array(), " name LIKE '%more%' ", array())), 3);
     asrt(count($redbean->find("page", array(), " name LIKE :str ", array(":str" => '%more%'))), 3);
     asrt(count($redbean->find("page", array(), array(" name LIKE :str ", array(":str" => '%more%')))), 3);
     asrt(count($redbean->find("page", array(), " name LIKE :str ", array(":str" => '%mxore%'))), 0);
     asrt(count($redbean->find("page", array("id" => array(2, 3)))), 2);
     $bean = $redbean->dispense("wine");
     $bean->name = "bla";
     for ($i = 0; $i < 10; $i++) {
         $redbean->store($bean);
     }
     $redbean->find("wine", array("id" => 5));
     //  Finder:where call OODB::convertToBeans
     $bean2 = $redbean->load("anotherbean", 5);
     asrt($bean2->id, 0);
     $keys = $adapter->getCol("SELECT id FROM page WHERE " . $writer->esc('name') . " LIKE '%John%'");
     asrt(count($keys), 2);
     $pages = $redbean->batch("page", $keys);
     asrt(count($pages), 2);
     $p = R::findLast('page');
     pass();
     $row = R::getRow('select * from page ');
     asrt(is_array($row), TRUE);
     asrt(isset($row['name']), TRUE);
     // Test findAll -- should not throw an exception
     asrt(count(R::findAll('page')) > 0, TRUE);
     asrt(count(R::findAll('page', ' ORDER BY id ')) > 0, TRUE);
     $beans = R::findOrDispense("page");
     asrt(count($beans), 6);
     asrt(is_null(R::findLast('nothing')), TRUE);
     try {
         R::find('bean', ' id > 0 ', 'invalid bindings argument');
         fail();
     } catch (RedException $exception) {
         pass();
     }
 }
Beispiel #9
0
 /**
  * Tests freezing the database.
  * After freezing the database, schema modifications are no longer
  * allowed and referring to missing columns will now cause exceptions.
  * 
  * @return void
  */
 public function testFreezer()
 {
     $toolbox = R::getToolBox();
     $adapter = $toolbox->getDatabaseAdapter();
     $writer = $toolbox->getWriter();
     $redbean = $toolbox->getRedBean();
     $pdo = $adapter->getDatabase();
     $a = new AssociationManager($toolbox);
     $post = $redbean->dispense('post');
     $post->title = 'title';
     $redbean->store($post);
     $page = $redbean->dispense('page');
     $page->name = 'title';
     $redbean->store($page);
     $page = $redbean->dispense("page");
     $page->name = "John's page";
     $idpage = $redbean->store($page);
     $page2 = $redbean->dispense("page");
     $page2->name = "John's second page";
     $idpage2 = $redbean->store($page2);
     $a->associate($page, $page2);
     $redbean->freeze(TRUE);
     $page = $redbean->dispense("page");
     $page->sections = 10;
     $page->name = "half a page";
     try {
         $id = $redbean->store($page);
         fail();
     } catch (SQL $e) {
         pass();
     }
     $post = $redbean->dispense("post");
     $post->title = "existing table";
     try {
         $id = $redbean->store($post);
         pass();
     } catch (SQL $e) {
         fail();
     }
     asrt(in_array("name", array_keys($writer->getColumns("page"))), TRUE);
     asrt(in_array("sections", array_keys($writer->getColumns("page"))), FALSE);
     $newtype = $redbean->dispense("newtype");
     $newtype->property = 1;
     try {
         $id = $redbean->store($newtype);
         fail();
     } catch (SQL $e) {
         pass();
     }
     $logger = R::debug(true, 1);
     // Now log and make sure no 'describe SQL' happens
     $page = $redbean->dispense("page");
     $page->name = "just another page that has been frozen...";
     $id = $redbean->store($page);
     $page = $redbean->load("page", $id);
     $page->name = "just a frozen page...";
     $redbean->store($page);
     $page2 = $redbean->dispense("page");
     $page2->name = "an associated frozen page";
     $a->associate($page, $page2);
     $a->related($page, "page");
     $a->unassociate($page, $page2);
     $a->clearRelations($page, "page");
     $items = $redbean->find("page", array(), array("1"));
     $redbean->trash($page);
     $redbean->freeze(FALSE);
     asrt(count($logger->grep("SELECT")) > 0, TRUE);
     asrt(count($logger->grep("describe")) < 1, TRUE);
     asrt(is_array($logger->getLogs()), TRUE);
     R::debug(false);
 }