Example #1
0
 /**
  * Does an optimization cycle for each UPDATE event.
  *
  * @param string				$event event
  * @param RedBean_OODBBean $bean	 bean
  *
  * @return void
  */
 public function onEvent($event, $bean)
 {
     try {
         if ($event == "update") {
             //export the bean as an array
             $arr = $bean->export();
             //print_r($arr);
             //remove the id property
             unset($arr["id"]);
             //If we are left with an empty array we might as well return
             if (count($arr) == 0) {
                 return;
             }
             //fetch table name for this bean
             //get the column names for this table
             $table = $bean->getMeta("type");
             $columns = array_keys($arr);
             //Select a random column for optimization.
             $column = $columns[array_rand($columns)];
             //get the value to be optimized
             $value = $arr[$column];
             $this->optimize($table, $column, $value);
         }
     } catch (RedBean_Exception_SQL $e) {
     }
 }
 public static function getKeys(RedBean_OODBBean $bean, $typeName)
 {
     $fieldName = self::getLinkField($typeName);
     $id = (int) $bean->{$fieldName};
     $ids = R::getCol("select id from {$typeName} where " . $bean->getMeta("type") . "_id" . " = {$bean->id}");
     return $ids;
 }
Example #3
0
 /**
  * Throws an exception if information in the bean has been changed
  * by another process or bean. This is actually the same as journaling
  * using timestamps however with timestamps you risk race conditions
  * when the measurements are not fine-grained enough; with
  * auto-incremented primary key ids we dont have this risk.
  * @param string $event
  * @param RedBean_OODBBean $item
  */
 public function onEvent($event, $item)
 {
     $id = $item->id;
     if (!(int) $id) {
         $event = "open";
     }
     $type = $item->getMeta("type");
     if ($event == "open") {
         if (isset($this->stash[$id])) {
             $insertid = $this->stash[$id];
             unset($this->stash[$id]);
             return $insertid;
         }
         $insertid = $this->writer->insertRecord("__log", array("action", "tbl", "itemid"), array(array(1, $type, $id)));
         $item->setMeta("opened", $insertid);
     }
     if ($event == "update" || $event == "delete") {
         if ($item->getMeta("opened")) {
             $oldid = $item->getMeta("opened");
         } else {
             $oldid = 0;
         }
         $newid = $this->checkChanges($type, $id, $oldid);
         $item->setMeta("opened", $newid);
     }
 }
 /**
  * Does an optimization cycle for each UPDATE event
  * @param string $event
  * @param RedBean_OODBBean $bean
  */
 public function onEvent($event, $bean)
 {
     try {
         if ($event == "update") {
             $arr = $bean->export();
             unset($arr["id"]);
             if (count($arr) == 0) {
                 return;
             }
             $table = $this->adapter->escape($bean->getMeta("type"));
             $columns = array_keys($arr);
             $column = $this->adapter->escape($columns[array_rand($columns)]);
             $value = $arr[$column];
             $type = $this->writer->scanType($value);
             $fields = $this->writer->getColumns($table);
             if (!in_array($column, array_keys($fields))) {
                 return;
             }
             $typeInField = $this->writer->code($fields[$column]);
             if ($type < $typeInField) {
                 $type = $this->writer->typeno_sqltype[$type];
                 $this->adapter->exec("alter table `{$table}` add __test " . $type);
                 $this->adapter->exec("update `{$table}` set __test=`{$column}`");
                 $diff = $this->adapter->getCell("select\n\t\t\t\t\t\t\tcount(*) as df from `{$table}` where\n\t\t\t\t\t\t\tstrcmp(`{$column}`,__test) != 0");
                 if (!$diff) {
                     $this->adapter->exec("alter table `{$table}` change `{$column}` `{$column}` " . $type);
                 }
                 $this->adapter->exec("alter table `{$table}` drop __test");
             }
         }
     } catch (RedBean_Exception_SQL $e) {
         //optimizer might make mistakes, dont care..
     }
 }
Example #5
0
 /**
  * Ensures that given an association between
  * $bean1 and $bean2,
  * if one of them gets trashed the association will be
  * automatically removed.
  * @param RedBean_OODBBean $bean1
  * @param RedBean_OODBBean $bean2
  * @return boolean $addedFKS
  */
 public static function addConstraint(RedBean_OODBBean $bean1, RedBean_OODBBean $bean2, $dontCache = false)
 {
     //Fetch the toolbox
     $toolbox = RedBean_Setup::getToolBox();
     RedBean_CompatManager::scanDirect($toolbox, array(RedBean_CompatManager::C_SYSTEM_MYSQL => "5"));
     //Create an association manager
     $association = new RedBean_AssociationManager($toolbox);
     $writer = $toolbox->getWriter();
     $oodb = $toolbox->getRedBean();
     $adapter = $toolbox->getDatabaseAdapter();
     //Frozen? Then we may not alter the schema!
     if ($oodb->isFrozen()) {
         return false;
     }
     //$adapter->getDatabase()->setDebugMode(1);
     $table1 = $bean1->getMeta("type");
     $table2 = $bean2->getMeta("type");
     $table = $association->getTable(array($table1, $table2));
     $idfield1 = $writer->getIDField($bean1->getMeta("type"));
     $idfield2 = $writer->getIDField($bean2->getMeta("type"));
     $bean = $oodb->dispense($table);
     $property1 = $bean1->getMeta("type") . "_id";
     $property2 = $bean2->getMeta("type") . "_id";
     if ($property1 == $property2) {
         $property2 = $bean2->getMeta("type") . "2_id";
     }
     $table = $adapter->escape($table);
     $table1 = $adapter->escape($table1);
     $table2 = $adapter->escape($table2);
     $property1 = $adapter->escape($property1);
     $property2 = $adapter->escape($property2);
     //In Cache? Then we dont need to bother
     if (isset(self::$fkcache[$table])) {
         return false;
     }
     $db = $adapter->getCell("select database()");
     $fks = $adapter->getCell("\n\t\t\tSELECT count(*)\n\t\t\tFROM information_schema.KEY_COLUMN_USAGE\n\t\t\tWHERE TABLE_SCHEMA ='{$db}' AND TABLE_NAME ='{$table}' AND\n\t\t\tCONSTRAINT_NAME <>'PRIMARY' AND REFERENCED_TABLE_NAME is not null\n\t\t");
     //already foreign keys added in this association table
     if ($fks > 0) {
         return false;
     }
     //add the table to the cache, so we dont have to fire the fk query all the time.
     if (!$dontCache) {
         self::$fkcache[$table] = true;
     }
     $columns = $writer->getColumns($table);
     if ($writer->code($columns[$property1]) !== RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32) {
         $writer->widenColumn($table, $property1, RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32);
     }
     if ($writer->code($columns[$property2]) !== RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32) {
         $writer->widenColumn($table, $property2, RedBean_QueryWriter_MySQL::C_DATATYPE_UINT32);
     }
     $sql = "\n\t\t\tALTER TABLE " . $writer->noKW($table) . "\n\t\t\tADD FOREIGN KEY({$property1}) references {$table1}(id) ON DELETE CASCADE;\n\n\t\t";
     $adapter->exec($sql);
     $sql = "\n\t\t\tALTER TABLE " . $writer->noKW($table) . "\n\t\t\tADD FOREIGN KEY({$property2}) references {$table2}(id) ON DELETE CASCADE\n\t\t";
     $adapter->exec($sql);
     return true;
 }
 /**
  *
  * @param RedBean_OODBBean $parent
  * @return array $childObjects
  */
 public function children(RedBean_OODBBean $parent)
 {
     try {
         $ids = $this->adapter->getCol("SELECT id FROM\n\t\t\t`" . $parent->getMeta("type") . "`\n\t\t\tWHERE `" . $this->property . "` = " . intval($parent->id) . "\n\t\t");
     } catch (RedBean_Exception_SQL $e) {
         return array();
     }
     return $this->oodb->batch($parent->getMeta("type"), $ids);
 }
 public static function getKeys(RedBean_OODBBean $bean, $typeName, $name = null)
 {
     $fieldName = self::getLinkField($typeName, $name);
     $id = (int) $bean->{$fieldName};
     $columnPrefix = self::resolveColumnPrefix($name);
     $columnName = $columnPrefix . $bean->getMeta("type") . '_id';
     $ids = ZurmoRedBean::getCol("select id from {$typeName} where " . $columnName . " = {$bean->id}");
     return $ids;
 }
 private function boxIfModel(\RedBean_OODBBean $bean)
 {
     $model = $bean->box();
     if (!$model instanceof Model) {
         return $bean;
     }
     $model->bindApp($this->app);
     return $model;
 }
Example #9
0
 /**
  * Returns all the nodes that have been attached to the specified
  * parent node.
  * @param RedBean_OODBBean $parent
  * @return array $childObjects
  */
 public function children(RedBean_OODBBean $parent)
 {
     $idfield = $this->writer->getIDField($parent->getMeta("type"));
     try {
         $ids = $this->writer->selectByCrit($idfield, $parent->getMeta("type"), $this->property, intval($parent->{$idfield}));
     } catch (RedBean_Exception_SQL $e) {
         return array();
     }
     return $this->oodb->batch($parent->getMeta("type"), $ids);
 }
Example #10
0
 /**
  * Tests whether getID never produces a notice.
  * 
  * @return void
  */
 public function testGetIDShouldNeverPrintNotice()
 {
     set_error_handler(function ($err, $errStr) {
         die('>>>>FAIL :' . $err . ' ' . $errStr);
     });
     $bean = new RedBean_OODBBean();
     $bean->getID();
     restore_error_handler();
     pass();
 }
Example #11
0
 /**
  * Does an optimization cycle for each UPDATE event.
  * @param string $event
  * @param RedBean_OODBBean $bean
  */
 public function onEvent($event, $bean)
 {
     try {
         if ($event == "update") {
             $arr = $bean->export();
             unset($arr["id"]);
             if (count($arr) == 0) {
                 return;
             }
             $table = $this->adapter->escape($bean->getMeta("type"));
             $columns = array_keys($arr);
             //Select a random column for optimization.
             $column = $this->adapter->escape($columns[array_rand($columns)]);
             $value = $arr[$column];
             $type = $this->writer->scanType($value);
             $fields = $this->writer->getColumns($table);
             if (!in_array($column, array_keys($fields))) {
                 return;
             }
             $typeInField = $this->writer->code($fields[$column]);
             //Is the type too wide?
             if ($type < $typeInField) {
                 try {
                     @$this->adapter->exec("alter table " . $this->writer->noKW($table) . " drop __test");
                 } catch (Exception $e) {
                 }
                 //Try to re-fit the entire column; by testing it.
                 $type = $this->writer->typeno_sqltype[$type];
                 //Add a test column.
                 @$this->adapter->exec("alter table " . $this->writer->noKW($table) . " add __test " . $type);
                 //Copy the values and see if there are differences.
                 @$this->adapter->exec("update " . $this->writer->noKW($table) . " set __test=" . $this->writer->noKW($column) . "");
                 $rows = $this->adapter->get("select " . $this->writer->noKW($column) . " as a, __test as b from " . $this->writer->noKW($table));
                 $diff = 0;
                 foreach ($rows as $row) {
                     $diff += $row["a"] != $row["b"];
                 }
                 if (!$diff) {
                     //No differences; shrink column.
                     @$this->adapter->exec("alter table " . $this->writer->noKW($table) . " change " . $this->writer->noKW($column) . " " . $this->writer->noKW($column) . " " . $type);
                 }
                 //Throw away test column; we don't need it anymore!
                 @$this->adapter->exec("alter table " . $this->writer->noKW($table) . " drop __test");
             } else {
                 $this->MySQLSpecificColumns($table, $column, $fields[$column], $value);
             }
         }
     } catch (RedBean_Exception_SQL $e) {
         //optimizer might make mistakes, don't care.
         //echo $e->getMessage()."<br>";
     }
 }
Example #12
0
 /**
  * Test import from and tainted.
  * 
  * @return void
  */
 public function testImportFromAndTainted()
 {
     testpack('Test importFrom() and Tainted');
     $bean = R::dispense('bean');
     R::store($bean);
     $bean->name = 'abc';
     asrt($bean->getMeta('tainted'), TRUE);
     R::store($bean);
     asrt($bean->getMeta('tainted'), FALSE);
     $copy = R::dispense('bean');
     R::store($copy);
     $copy = R::load('bean', $copy->id);
     asrt($copy->getMeta('tainted'), FALSE);
     $copy->import(array('name' => 'xyz'));
     asrt($copy->getMeta('tainted'), TRUE);
     $copy->setMeta('tainted', FALSE);
     asrt($copy->getMeta('tainted'), FALSE);
     $copy->importFrom($bean);
     asrt($copy->getMeta('tainted'), TRUE);
     testpack('Test basic import() feature.');
     $bean = new RedBean_OODBBean();
     $bean->import(array("a" => 1, "b" => 2));
     asrt($bean->a, 1);
     asrt($bean->b, 2);
     $bean->import(array("a" => 3, "b" => 4), "a,b");
     asrt($bean->a, 3);
     asrt($bean->b, 4);
     $bean->import(array("a" => 5, "b" => 6), " a , b ");
     asrt($bean->a, 5);
     asrt($bean->b, 6);
     $bean->import(array("a" => 1, "b" => 2));
     testpack('Test inject() feature.');
     $coffee = R::dispense('coffee');
     $coffee->id = 2;
     $coffee->liquid = 'black';
     $cup = R::dispense('cup');
     $cup->color = 'green';
     // Pour coffee in cup
     $cup->inject($coffee);
     // Do we still have our own property?
     asrt($cup->color, 'green');
     // Did we pour the liquid in the cup?
     asrt($cup->liquid, 'black');
     // Id should not be transferred
     asrt($cup->id, 0);
 }
Example #13
0
 /**
  * Returns the alias for a type
  *
  * @param  $type aliased type
  *
  * @return string $type type
  */
 public function getAlias($type)
 {
     if ($t = RedBean_OODBBean::$fetchType) {
         $type = $t;
         RedBean_OODBBean::$fetchType = null;
     }
     return $type;
 }
Example #14
0
 /**
  * Checks whether a bean is valid
  * @param RedBean_OODBBean $bean
  */
 public function check(RedBean_OODBBean $bean)
 {
     //Is all meta information present?
     if (!isset($bean->id) || !$bean->getMeta("type")) {
         throw new RedBean_Exception_Security("Bean has incomplete Meta Information");
     }
     //Pattern of allowed characters
     $pattern = '/[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]/';
     //Does the type contain invalid characters?
     if (preg_match($pattern, $bean->getMeta("type"))) {
         throw new RedBean_Exception_Security("Bean Type is invalid");
     }
     //Are the properties and values valid?
     foreach ($bean as $prop => $value) {
         if (is_array($value) || is_object($value) || strlen($prop) < 1 || preg_match($pattern, $prop)) {
             throw new RedBean_Exception_Security("Invalid Bean: property {$prop}  ");
         }
     }
 }
 /**
  * Returns all beans that have been tagged with one or more
  * of the specified tags.
  * 
  * Tag list can be either an array with tag names or a comma separated list
  * of tag names.
  *
  * @param string       $beanType type of bean you are looking for
  * @param array|string $tagList  list of tags to match
  *
  * @return array
  */
 public function tagged($beanType, $tagList)
 {
     $tags = $this->extractTagsIfNeeded($tagList);
     $collection = array();
     $tags = $this->redbean->find('tag', array('title' => $tags));
     if (is_array($tags) && count($tags) > 0) {
         $collectionKeys = $this->associationManager->related($tags, $beanType);
         if ($collectionKeys) {
             $collection = $this->redbean->batch($beanType, $collectionKeys);
         }
     }
     return $collection;
 }
Example #16
0
 /**
  * Test meta data methods.
  * 
  * @return void
  */
 public function testMetaData()
 {
     testpack('Test meta data');
     $bean = new RedBean_OODBBean();
     $bean->setMeta("this.is.a.custom.metaproperty", "yes");
     asrt($bean->getMeta("this.is.a.custom.metaproperty"), "yes");
     asrt($bean->getMeta("nonexistant"), NULL);
     asrt($bean->getMeta("nonexistant", "abc"), "abc");
     asrt($bean->getMeta("nonexistant.nested"), NULL);
     asrt($bean->getMeta("nonexistant,nested", "abc"), "abc");
     $bean->setMeta("test.two", "second");
     asrt($bean->getMeta("test.two"), "second");
     $bean->setMeta("another.little.property", "yes");
     asrt($bean->getMeta("another.little.property"), "yes");
     asrt($bean->getMeta("test.two"), "second");
     // Copy Metadata
     $bean = new RedBean_OODBBean();
     $bean->setMeta("meta.meta", "123");
     $bean2 = new RedBean_OODBBean();
     asrt($bean2->getMeta("meta.meta"), NULL);
     $bean2->copyMetaFrom($bean);
     asrt($bean2->getMeta("meta.meta"), "123");
 }
 /**
  *
  * @param RedBean_OODBBean $parent
  * @return array $childObjects
  */
 public function children(RedBean_OODBBean $parent)
 {
     $idfield = $this->writer->getIDField($parent->getMeta("type"));
     try {
         /*
         $ids = $this->adapter->getCol("SELECT `".$idfield."` FROM
         	`".$parent->getMeta("type")."`
         	WHERE `".$this->property."` = ".intval( $parent->$idfield )."
         ");
         */
         /*
         		$ids = $this->adapter->getCol($this->writer->buildSimpleQuery(
         			"select",array($idfield),$parent->getMeta("type"),
         			array("name"=>$this->property,
         				  "value"=>intval($parent->$idfield),
         				  "operator"=>"=","structure"=>"")
         		));
         */
         $ids = $this->writer->selectByCrit($idfield, $parent->getMeta("type"), $this->property, intval($parent->{$idfield}));
     } catch (RedBean_Exception_SQL $e) {
         return array();
     }
     return $this->oodb->batch($parent->getMeta("type"), $ids);
 }
 /**
  * Test if RedBeanPHP can properly handle keywords.
  * 
  * @return void
  */
 public function testKeywords()
 {
     $keywords = array('anokeyword', 'znokeyword', 'group', 'DROP', 'inner', 'JOIN', 'select', 'table', 'int', 'cascade', 'float', 'CALL', 'in', 'status', 'order', 'limit', 'having', 'else', 'if', 'while', 'distinct', 'like');
     R::setStrictTyping(FALSE);
     RedBean_OODBBean::setFlagBeautifulColumnNames(FALSE);
     foreach ($keywords as $k) {
         R::nuke();
         $bean = R::dispense($k);
         $bean->{$k} = $k;
         $id = R::store($bean);
         $bean = R::load($k, $id);
         $bean2 = R::dispense('other');
         $bean2->name = $k;
         $bean->bean = $bean2;
         $bean->ownBean[] = $bean2;
         $bean->sharedBean[] = $bean2;
         $id = R::store($bean);
         R::trash($bean);
         pass();
     }
     RedBean_OODBBean::setFlagBeautifulColumnNames(TRUE);
     R::setStrictTyping(TRUE);
 }
Example #19
0
 /**
  * Generates a key from the bean type and its ID and determines if the bean
  * occurs in the trail, if not the bean will be added to the trail.
  * Returns TRUE if the bean occurs in the trail and FALSE otherwise.
  *
  * @param array            $trail list of former beans
  * @param RedBean_OODBBean $bean  currently selected bean
  *
  * @return boolean
  */
 private function inTrailOrAdd(&$trail, RedBean_OODBBean $bean)
 {
     $type = $bean->getMeta('type');
     $key = $type . $bean->getID();
     if (isset($trail[$key])) {
         return TRUE;
     }
     $trail[$key] = $bean;
     return FALSE;
 }
 /**
  * Creates a 1 to Many Association
  * If the association fails it throws an exception.
  * @throws RedBean_Exception_SQL $failedToEnforce1toN
  * @param RedBean_OODBBean $bean1
  * @param RedBean_OODBBean $bean2
  * @return RedBean_AssociationManager $chainable
  */
 public function set1toNAssoc(RedBean_OODBBean $bean1, RedBean_OODBBean $bean2)
 {
     $type = $bean1->getMeta("type");
     $this->clearRelations($bean2, $type);
     $this->associate($bean1, $bean2);
     if (count($this->related($bean2, $type)) === 1) {
         return $this;
     } else {
         throw new RedBean_Exception_SQL("Failed to enforce 1toN Relation for {$type} ");
     }
 }
Example #21
0
$default_config['default_sql_limit'] = array(0, 25);
$default_config['rate_limit'] = 100;
$config = array_merge($default_config, $config);
if (file_exists('config.php.default') && $config['debug'] === false) {
    die('Please remove the config.php.default.');
}
require_once 'utils.php';
/* make sure admin pass has changed */
if ($config['password'] === 'admin') {
    die('Change the password in config.php');
}
/* setup database */
use RedBean_Facade as R;
R::setup($config['db_conn'], $config['db_user'], $config['db_pass']);
R::$writer->setUseCache(false);
RedBean_OODBBean::setFlagBeautifulColumnNames(false);
/* app start */
if ($config['debug'] === false) {
    ini_set('display_errors', '0');
}
$app = new \Slim\Slim(array('debug' => $config['debug'], 'templates.path' => 'templates'));
/* Middlewares */
$r = new Util($app);
/* load hooks */
$r->loadHooks();
function API()
{
    $app = \Slim\Slim::getInstance();
    $app->view(new \JsonApiView());
    $app->add(new \JsonApiMiddleware());
    $app->response->headers->set('Content-Type', 'application/json');
Example #22
0
 /**
  * Returns the ID of the Model.
  */
 public function getID()
 {
     $idField = $this->tools->getWriter()->getIDField($this->bean->getMeta("type"));
     return $this->bean->{$idField};
 }
 /**
  * Injects the properties of another bean but keeps the original ID.
  * Just like import() but keeps the original ID.
  * Chainable.
  *
  * @param RedBean_OODBBean $otherBean the bean whose properties you would like to copy
  *
  * @return RedBean_OODBBean
  */
 public function inject(RedBean_OODBBean $otherBean)
 {
     $myID = $this->properties['id'];
     $this->import($otherBean->export());
     $this->id = $myID;
     return $this;
 }
Example #24
0
 /**
  * Counts the number of beans of a specific type
  * @param RedBean_OODBBean $bean
  * @return integer $count
  */
 public function numberOf(RedBean_OODBBean $bean)
 {
     $type = $this->adapter->escape($bean->getMeta("type"));
     return (int) $this->adapter->getCell("SELECT count(*) FROM `{$type}`");
 }
Example #25
0
 /**
  * Returns the bean identified by the RESTful path.
  * For instance:
  *
  *        $user
  *        /site/1/page/3
  *
  * returns page with ID 3 in ownPage of site 1 in ownSite of
  * $user bean.
  *
  * Works with shared lists as well:
  *
  *        $user
  *        /site/1/page/3/shared-ad/4
  *
  * Note that this method will open all intermediate beans so you can
  * attach access control rules to each bean in the path.
  *
  * @param RedBean_OODBBean $bean
  * @param array            $steps  (an array representation of a REST path)
  *
  * @return RedBean_OODBBean
  *
  * @throws RedBean_Exception_Security
  */
 public function findByPath($bean, $steps)
 {
     $numberOfSteps = count($steps);
     if (!$numberOfSteps) {
         return $bean;
     }
     if ($numberOfSteps % 2) {
         throw new RedBean_Exception_Security('Invalid path: needs 1 more element.');
     }
     for ($i = 0; $i < $numberOfSteps; $i += 2) {
         $steps[$i] = trim($steps[$i]);
         if ($steps[$i] === '') {
             throw new RedBean_Exception_Security('Cannot access list.');
         }
         if (strpos($steps[$i], 'shared-') === FALSE) {
             $listName = 'own' . ucfirst($steps[$i]);
             $listType = $this->toolbox->getWriter()->esc($steps[$i]);
         } else {
             $listName = 'shared' . ucfirst(substr($steps[$i], 7));
             $listType = $this->toolbox->getWriter()->esc(substr($steps[$i], 7));
         }
         $list = $bean->withCondition(" {$listType}.id = ? ", array($steps[$i + 1]))->{$listName};
         if (!isset($list[$steps[$i + 1]])) {
             throw new RedBean_Exception_Security('Cannot access bean.');
         }
         $bean = $list[$steps[$i + 1]];
     }
     return $bean;
 }
Example #26
0
 /**
  * Makes a copy of a bean. This method makes a deep copy
  * of the bean.The copy will have the following features.
  * - All beans in own-lists will be duplicated as well
  * - All references to shared beans will be copied but not the shared beans themselves
  * - All references to parent objects (_id fields) will be copied but not the parents themselves
  * In most cases this is the desired scenario for copying beans.
  * This function uses a trail-array to prevent infinite recursion, if a recursive bean is found
  * (i.e. one that already has been processed) the ID of the bean will be returned.
  * This should not happen though.
  *
  * Note:
  * This function does a reflectional database query so it may be slow.
  *
  * @param RedBean_OODBBean $bean  bean to be copied
  * @param array            $trail for internal usage, pass array()
  * @param boolean          $pid   for internal usage
  *
  * @return array $copiedBean the duplicated bean
  */
 protected function duplicate($bean, $trail = array(), $pid = false)
 {
     $type = $bean->getMeta('type');
     $key = $type . $bean->getID();
     if (isset($trail[$key])) {
         return $bean;
     }
     $trail[$key] = $bean;
     $copy = $this->redbean->dispense($type);
     $copy->import($bean->getProperties());
     $copy->id = 0;
     $tables = $this->toolbox->getWriter()->getTables();
     foreach ($tables as $table) {
         if (strpos($table, '_') !== false || $table == $type) {
             continue;
         }
         $owned = 'own' . ucfirst($table);
         $shared = 'shared' . ucfirst($table);
         if ($beans = $bean->{$owned}) {
             $copy->{$owned} = array();
             foreach ($beans as $subBean) {
                 array_push($copy->{$owned}, $this->duplicate($subBean, $trail, $pid));
             }
         }
         $copy->setMeta('sys.shadow.' . $owned, null);
         if ($beans = $bean->{$shared}) {
             $copy->{$shared} = array();
             foreach ($beans as $subBean) {
                 array_push($copy->{$shared}, $subBean);
             }
         }
         $copy->setMeta('sys.shadow.' . $shared, null);
     }
     if ($pid) {
         $copy->id = $bean->id;
     }
     return $copy;
 }
Example #27
0
 /**
  * Removes a bean from the database.
  * This function will remove the specified RedBean_OODBBean
  * Bean Object from the database.
  * @throws RedBean_Exception_Security $exception
  * @param RedBean_OODBBean $bean
  */
 public function trash(RedBean_OODBBean $bean)
 {
     $idfield = $this->writer->getIDField($bean->getMeta("type"));
     $this->signal("delete", $bean);
     $this->check($bean);
     try {
         $this->writer->deleteRecord($bean->getMeta("type"), $bean->{$idfield});
     } catch (RedBean_Exception_SQL $e) {
         if ($e->getSQLState() != "42S02" && $e->getSQLState() != "42S22") {
             throw $e;
         }
     }
 }
Example #28
0
 /**
  * Adds a constraint. If one of the beans gets trashed
  * the other, related bean should be removed as well.
  *
  * @param RedBean_OODBBean $bean1      first bean
  * @param RedBean_OODBBean $bean2      second bean
  * @param bool 			   $dontCache  by default we use a cache, TRUE = NO CACHING (optional)
  *
  * @return void
  */
 public function addConstraint(RedBean_OODBBean $bean1, RedBean_OODBBean $bean2, $dontCache = false)
 {
     $table1 = $bean1->getMeta("type");
     $table2 = $bean2->getMeta("type");
     $writer = $this;
     $adapter = $this->adapter;
     $table = $this->getAssocTableFormat(array($table1, $table2));
     $idfield1 = $writer->getIDField($bean1->getMeta("type"));
     $idfield2 = $writer->getIDField($bean2->getMeta("type"));
     $property1 = $bean1->getMeta("type") . "_id";
     $property2 = $bean2->getMeta("type") . "_id";
     if ($property1 == $property2) {
         $property2 = $bean2->getMeta("type") . "2_id";
     }
     $table = $adapter->escape($table);
     $table1 = $adapter->escape($table1);
     $table2 = $adapter->escape($table2);
     $property1 = $adapter->escape($property1);
     $property2 = $adapter->escape($property2);
     //In Cache? Then we dont need to bother
     $fkCode = "fk" . md5($table . $property1 . $property2);
     if (isset($this->fkcache[$fkCode])) {
         return false;
     }
     //Dispatch to right method
     try {
         return $this->constrain($table, $table1, $table2, $property1, $property2, $dontCache);
     } catch (RedBean_Exception_SQL $e) {
         if (!$writer->sqlStateIn($e->getSQLState(), array(RedBean_QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN, RedBean_QueryWriter::C_SQLSTATE_NO_SUCH_TABLE))) {
             throw $e;
         }
     }
     return false;
 }
Example #29
0
 /**
  * Creates a 1 to Many Association
  * @param RedBean_OODBBean $bean1
  * @param RedBean_OODBBean $bean2
  */
 public function set1toNAssoc(RedBean_OODBBean $bean1, RedBean_OODBBean $bean2)
 {
     $this->clearRelations($bean2, $bean1->getMeta("type"));
     $this->associate($bean1, $bean2);
 }
Example #30
0
 /**
  * Used for mixins.
  */
 protected function mapAndCacheMetadataAndSetHints($modelClassName, RedBean_OODBBean $bean)
 {
     assert('is_string($modelClassName)');
     assert('$modelClassName != ""');
     $metadata = $this->getMetadata();
     if (isset($metadata[$modelClassName])) {
         $hints = array();
         if (isset($metadata[$modelClassName]['members'])) {
             foreach ($metadata[$modelClassName]['members'] as $memberName) {
                 $this->attributeNameToBeanAndClassName[$memberName] = array($bean, $modelClassName);
                 //$this->attributeNamesNotBelongsToOrManyMany[] = $memberName;
                 if (substr($memberName, -2) == 'Id') {
                     $columnName = strtolower($memberName);
                     $hints[$columnName] = 'id';
                 }
             }
         }
         if (isset($metadata[$modelClassName]['relations'])) {
             foreach ($metadata[$modelClassName]['relations'] as $relationName => $relationTypeModelClassNameAndOwns) {
                 assert('in_array(count($relationTypeModelClassNameAndOwns), array(2, 3, 4, 5))');
                 $relationType = $relationTypeModelClassNameAndOwns[0];
                 $relationModelClassName = $relationTypeModelClassNameAndOwns[1];
                 if ($relationType == self::HAS_MANY_BELONGS_TO && strtolower($relationName) != strtolower($relationModelClassName)) {
                     $label = 'Relations of type HAS_MANY_BELONGS_TO must have the relation name ' . 'the same as the related model class name. Relation: {relationName} ' . 'Relation model class name: {relationModelClassName}';
                     throw new NotSupportedException(Zurmo::t('Core', $label, array('{relationName}' => $relationName, '{relationModelClassName}' => $relationModelClassName)));
                 }
                 if (count($relationTypeModelClassNameAndOwns) >= 3 && $relationTypeModelClassNameAndOwns[2] == self::OWNED) {
                     $owns = true;
                 } else {
                     $owns = false;
                 }
                 // $linkType          = null;
                 // $relationLinkName  = null;
                 // self::resolveLinkTypeAndRelationLinkName($relationTypeModelClassNameAndOwns, $linkType,
                 //                                          $relationLinkName);
                 assert('in_array($relationType, array(self::HAS_ONE_BELONGS_TO, self::HAS_MANY_BELONGS_TO, ' . 'self::HAS_ONE, self::HAS_MANY, self::MANY_MANY))');
                 $this->attributeNameToBeanAndClassName[$relationName] = array($bean, $modelClassName);
                 /**
                                         $this->relationNameToRelationTypeModelClassNameAndOwns[$relationName] = array($relationType,
                                                                                                                 $relationModelClassName,
                                                                                                                 $owns,
                                                                                                                 $linkType,
                                                                                                                 $relationLinkName);
                                          * **/
                 if (!in_array($relationType, array(self::HAS_ONE_BELONGS_TO, self::HAS_MANY_BELONGS_TO, self::MANY_MANY))) {
                     //$this->attributeNamesNotBelongsToOrManyMany[] = $relationName;
                 }
             }
         }
         // Add model validators. Parent validators are already applied.
         if (isset($metadata[$modelClassName]['rules'])) {
             foreach ($metadata[$modelClassName]['rules'] as $validatorMetadata) {
                 assert('isset($validatorMetadata[0])');
                 assert('isset($validatorMetadata[1])');
                 $attributeName = $validatorMetadata[0];
                 // Each rule in RedBeanModel must specify one attribute name.
                 // This was just better style, now it is mandatory.
                 assert('strpos($attributeName, " ") === false');
                 $validatorName = $validatorMetadata[1];
                 $validatorParameters = array_slice($validatorMetadata, 2);
                 if (isset(CValidator::$builtInValidators[$validatorName])) {
                     $validatorName = CValidator::$builtInValidators[$validatorName];
                 }
                 if (isset(self::$yiiValidatorsToRedBeanValidators[$validatorName])) {
                     $validatorName = self::$yiiValidatorsToRedBeanValidators[$validatorName];
                 }
                 $validator = CValidator::createValidator($validatorName, $this, $attributeName, $validatorParameters);
                 switch ($validatorName) {
                     case 'RedBeanModelTypeValidator':
                     case 'TypeValidator':
                         $columnName = strtolower($attributeName);
                         if (array_key_exists($columnName, $hints)) {
                             unset($hints[$columnName]);
                         }
                         if (in_array($validator->type, array('date', 'datetime', 'blob', 'longblob', 'string', 'text', 'longtext'))) {
                             $hints[$columnName] = $validator->type;
                         }
                         break;
                     case 'CBooleanValidator':
                         $columnName = strtolower($attributeName);
                         $hints[$columnName] = 'boolean';
                         break;
                     case 'RedBeanModelUniqueValidator':
                         if (!static::isRelation($attributeName)) {
                             $bean->setMeta("buildcommand.unique", array(array($attributeName)));
                         } else {
                             $relationAndOwns = static::getRelationNameToRelationTypeModelClassNameAndOwnsForModel();
                             $relatedModelClassName = $relationAndOwns[$attributeName][1];
                             $relatedModelTableName = self::getTableName($relatedModelClassName);
                             $columnName = strtolower($attributeName);
                             if ($columnName != $relatedModelTableName) {
                                 $columnName .= '_' . $relatedModelTableName;
                             }
                             $columnName .= '_id';
                             $bean->setMeta("buildcommand.unique", array(array($columnName)));
                         }
                         break;
                 }
                 $this->validators[] = $validator;
             }
             // Check if we need to update string type to long string type, based on validators.
             if (isset($metadata[$modelClassName]['members'])) {
                 foreach ($metadata[$modelClassName]['members'] as $memberName) {
                     $allValidators = $this->getValidators($memberName);
                     if (!empty($allValidators)) {
                         foreach ($allValidators as $validator) {
                             if ((get_class($validator) == 'RedBeanModelTypeValidator' || get_class($validator) == 'TypeValidator') && $validator->type == 'string') {
                                 $columnName = strtolower($validator->attributes[0]);
                                 if (count($allValidators) > 1) {
                                     $haveCStringValidator = false;
                                     foreach ($allValidators as $innerValidator) {
                                         if (get_class($innerValidator) == 'CStringValidator' && isset($innerValidator->max) && $innerValidator->max > 0) {
                                             if ($innerValidator->max > 65535) {
                                                 $hints[$columnName] = 'longtext';
                                             } elseif ($innerValidator->max < 255) {
                                                 $hints[$columnName] = "string({$innerValidator->max})";
                                             } else {
                                                 $hints[$columnName] = 'text';
                                             }
                                         }
                                         if (get_class($innerValidator) == 'CStringValidator') {
                                             $haveCStringValidator = true;
                                         }
                                     }
                                     if (!$haveCStringValidator) {
                                         $hints[$columnName] = 'text';
                                     }
                                 } else {
                                     $hints[$columnName] = 'text';
                                 }
                             }
                         }
                     }
                 }
             }
         }
         $bean->setMeta('hint', $hints);
     }
 }