/** * * @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); }
/** * 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); }
/** * Constructor, requires a writer * @param RedBean_QueryWriter $writer */ public function __construct(RedBean_ToolBox $toolbox) { $this->writer = $toolbox->getWriter(); $this->adapter = $toolbox->getDatabaseAdapter(); $this->redbean = $toolbox->getRedBean(); if ($this->redbean->isFrozen()) { $this->adapter->exec("\n\t\t\t\t\t\tCREATE TABLE IF NOT EXISTS `__log` (\n\t\t\t\t\t\t`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,\n\t\t\t\t\t\t`tbl` VARCHAR( 255 ) NOT NULL ,\n\t\t\t\t\t\t`action` TINYINT( 2 ) NOT NULL ,\n\t\t\t\t\t\t`itemid` INT( 11 ) NOT NULL\n\t\t\t\t\t\t) ENGINE = MYISAM ;\n\t\t\t\t"); //Must be MyISAM! else you run in trouble if you use transactions! } $maxid = $this->adapter->getCell("SELECT MAX(id) FROM __log"); $this->adapter->exec("DELETE FROM __log WHERE id < {$maxid} - 200 "); }
/** * @param string $dsn * @param string $username * @param string $password * @return RedBean_ToolBox $toolbox */ public static function kickstart($dsn, $username, $password) { $pdo = new Redbean_Driver_PDO($dsn, $username, $password); $adapter = new RedBean_DBAdapter($pdo); $writer = new RedBean_QueryWriter_MySQL($adapter); $redbean = new RedBean_OODB($writer); //add concurrency shield $logger = new RedBean_ChangeLogger($writer); self::$observers["logger"] = $logger; $redbean->addEventListener("open", $logger); $redbean->addEventListener("update", $logger); $redbean->addEventListener("delete", $logger); //deliver everything back in a neat toolbox self::$toolbox = new RedBean_ToolBox($redbean, $adapter, $writer); return self::$toolbox; }
/** * Creates a view with name $viewID based on $refType bean type * and then left-joining the specified types in $types in the given * order. * * @param string $viewID desired name of the view * @param string $refType first bean type to be used as base * @param array $types array with types to be left-joined in view * * @return boolean $success whether we created a new view (false if already exists) */ public function createView($viewID, $refType, $types) { if ($this->oodb->isFrozen()) { return false; } $history = array(); $tables = array_flip($this->writer->getTables()); $refTable = $refType; //$this->writer->safeTable($refType, true); $currentTable = $refTable; $history[$refType] = $refType; foreach ($types as $t) { if (!isset($history[$t])) { $history[$t] = $t; $connection = array($t, $currentTable); sort($connection); $connection = implode("_", $connection); $connectionTable = $this->writer->safeTable($connection, true); if (isset($tables[$connectionTable])) { //this connection exists $srcPoint = $this->writer->safeTable($connection) . "." . $this->writer->safeColumn($currentTable . "_id"); //i.e. partic_project.project_id $dstPoint = $this->writer->safeTable($currentTable) . "." . $this->writer->safeColumn($this->writer->getIDField($currentTable)); //i.e. project.id $joins[$connection] = array($srcPoint, $dstPoint); //now join the type $srcPoint = $this->writer->safeTable($connection) . "." . $this->writer->safeColumn($t . "_id"); $dstPoint = $this->writer->safeTable($t) . "." . $this->writer->safeColumn($this->writer->getIDField($t)); $joins[$t] = array($srcPoint, $dstPoint); } else { //this connection does not exist $srcPoint = $this->writer->safeTable($t) . "." . $this->writer->safeColumn($currentTable . "_id"); $dstPoint = $this->writer->safeTable($currentTable) . "." . $this->writer->safeColumn($this->writer->getIDField($currentTable)); $joins[$t] = array($srcPoint, $dstPoint); } } //now set the new refTable $currentTable = $t; } try { $rs = (bool) $this->writer->createView($refType, $joins, $viewID); } catch (Exception $e) { throw new RedBean_Exception_SQL('Could not create view, types does not seem related (yet)..'); } return $rs; }
/** * @see RedBean_Finder::find * Convience method. Tries to find beans of a certain type, * if no beans are found, it dispenses a bean of that type. * * @param string $type the type of bean you are looking for * @param string $sql SQL query to find the desired bean, starting right after WHERE clause * @param array $bindings values array of values to be bound to parameters in query * * @return array */ public function findOrDispense($type, $sql = NULL, $bindings = array()) { $foundBeans = $this->find($type, $sql, $bindings); if (empty($foundBeans)) { return array($this->redbean->dispense($type)); } else { return $foundBeans; } }
public function __set($canwe, $v) { if ($canwe == "testPack") { $this->testPack = $v; echo "<br>processing testpack: " . RedBean_OODB::getEngine() . "-" . $v . " ...now testing: "; ob_flush(); flush(); } }
/** * Initializes the database and prepares a toolbox. * The kickstart method assembles a toolbox based on your DSN and * credentials and returns it. * The toolbox contains all the necessary core components for * RedBeanPHP to start working with your database. Most RedBeanPHP * components are stand-alone and require a toolbox to work. * * @param string|PDO $dsn Database Connection String (or PDO instance) * @param string $username Username for database * @param string $password Password for database * @param boolean $frozen Start in frozen mode? * * @return RedBean_ToolBox */ public static function kickstart($dsn, $username = NULL, $password = NULL, $frozen = FALSE, $autoSetEncoding = TRUE) { if ($dsn instanceof PDO) { $db = new RedBean_Driver_PDO($dsn); $dsn = $db->getDatabaseType(); } else { self::checkDSN($dsn); if (strpos($dsn, 'oracle') === 0) { $db = new RedBean_Driver_OCI($dsn, $username, $password); } else { $db = new RedBean_Driver_PDO($dsn, $username, $password, $autoSetEncoding); } } $adapter = new RedBean_Adapter_DBAdapter($db); if (strpos($dsn, 'pgsql') === 0) { $writer = new RedBean_QueryWriter_PostgreSQL($adapter); } else { if (strpos($dsn, 'sqlite') === 0) { $writer = new RedBean_QueryWriter_SQLiteT($adapter); } else { if (strpos($dsn, 'cubrid') === 0) { $writer = new RedBean_QueryWriter_CUBRID($adapter); } else { if (strpos($dsn, 'oracle') === 0) { $writer = new RedBean_QueryWriter_Oracle($adapter); } else { $writer = new RedBean_QueryWriter_MySQL($adapter); } } } } $redbean = new RedBean_OODB($writer); if ($frozen) { $redbean->freeze(TRUE); } $toolbox = new RedBean_ToolBox($redbean, $adapter, $writer); return $toolbox; }
/** * Loads bean, recurses if one of the property appears to be a list. * * @param array $array data array to import as a bean * @param boolean $filterEmpty if TRUE empty STRING values are converted to NULL (default FALSE) * * @return RedBean_OODBBean * * @throws RedBean_Exception_Security */ private function loadBean(&$array, $filterEmpty) { $type = $array['type']; unset($array['type']); if (isset($array['id'])) { // Do we need to load the bean? if (self::$loadBeans) { $bean = $this->redbean->load($type, (int) $array['id']); } else { throw new RedBean_Exception_Security('Attempt to load a bean in Cooker. Use enableBeanLoading to override but please read security notices first.'); } } else { $bean = $this->redbean->dispense($type); } foreach ($array as $property => $value) { if (is_array($value)) { $bean->{$property} = $this->graph($value, $filterEmpty); } else { $bean->{$property} = $value == '' && self::$useNULLForEmptyString ? NULL : $value; } } return $bean; }
/** * Returns all the beans associated with $bean. * This method will return an array containing all the beans that have * been associated once with the associate() function and are still * associated with the bean specified. The type parameter indicates the * type of beans you are looking for. You can also pass some extra SQL and * values for that SQL to filter your results after fetching the * related beans. * * Don't try to make use of subqueries, a subquery using IN() seems to * be slower than two queries! * * Since 3.2, you can now also pass an array of beans instead just one * bean as the first parameter. * * @param RedBean_OODBBean|array $bean the bean you have * @param string $type the type of beans you want * @param string $sql SQL snippet for extra filtering * @param array $bindings values to be inserted in SQL slots * @param boolean $glue whether the SQL should be prefixed with WHERE * * @return array */ public function relatedSimple($bean, $type, $sql = '', $bindings = array()) { $sql = $this->writer->glueSQLCondition($sql); $rows = $this->relatedRows($bean, $type, FALSE, $sql, $bindings); $links = array(); foreach ($rows as $key => $row) { if (!isset($links[$row['id']])) { $links[$row['id']] = array(); } $links[$row['id']][] = $row['linked_by']; unset($rows[$key]['linked_by']); } $beans = $this->oodb->convertToBeans($type, $rows); foreach ($beans as $bean) { $bean->setMeta('sys.belongs-to', $links[$bean->id]); } return $beans; }
/** * Removes all relations for a bean. This method breaks every connection between * a certain bean $bean and every other bean of type $type. Warning: this method * is really fast because it uses a direct SQL query however it does not inform the * models about this. If you want to notify FUSE models about deletion use a foreach-loop * with unassociate() instead. (that might be slower though) * * @param RedBean_OODBBean $bean reference bean * @param string $type type of beans that need to be unassociated * * @return void */ public function clearRelations(RedBean_OODBBean $bean, $type) { $this->oodb->store($bean); $table = $this->getTable(array($bean->getMeta("type"), $type)); $idfield = $this->writer->getIDField($bean->getMeta("type")); if ($type == $bean->getMeta("type")) { $property2 = $type . "2_id"; $cross = 1; } else { $cross = 0; } $property = $bean->getMeta("type") . "_id"; try { $this->writer->selectRecord($table, array($property => array($bean->{$idfield})), null, true); if ($cross) { $this->writer->selectRecord($table, array($property2 => array($bean->{$idfield})), null, true); } } catch (RedBean_Exception_SQL $e) { if (!$this->writer->sqlStateIn($e->getSQLState(), array(RedBean_QueryWriter::C_SQLSTATE_NO_SUCH_COLUMN, RedBean_QueryWriter::C_SQLSTATE_NO_SUCH_TABLE))) { throw $e; } } }
/** * Removes all relations for a bean * @param RedBean_OODBBean $bean * @param string $type */ public function clearRelations(RedBean_OODBBean $bean, $type) { $this->oodb->store($bean); $table = $this->getTable(array($bean->getMeta("type"), $type)); $idfield = $this->writer->getIDField($bean->getMeta("type")); if ($type == $bean->getMeta("type")) { $property2 = $type . "2_id"; $cross = 1; } else { $cross = 0; } $property = $bean->getMeta("type") . "_id"; try { $this->writer->deleteByCrit($table, array($property => $bean->{$idfield})); if ($cross) { $this->writer->deleteByCrit($table, array($property2 => $bean->{$idfield})); } } catch (RedBean_Exception_SQL $e) { if ($e->getSQLState() != "42S02" && $e->getSQLState() != "42S22") { throw $e; } } }
/** * * @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); }
/** * Removes all relations for a bean * @param RedBean_OODBBean $bean * @param <type> $type */ public function clearRelations(RedBean_OODBBean $bean, $type) { $this->oodb->store($bean); $table = $this->getTable(array($bean->getMeta("type"), $type)); $idfield = $this->writer->getIDField($bean->getMeta("type")); if ($type == $bean->getMeta("type")) { $property2 = $type . "2_id"; $cross = 1; } else { $cross = 0; } $property = $bean->getMeta("type") . "_id"; $sql = "DELETE FROM `{$table}`\n\t\tWHERE " . $this->adapter->escape($property) . " = " . $this->adapter->escape($bean->{$idfield}); if ($cross) { $sql .= " OR " . $this->adapter->escape($property2) . " = " . $this->adapter->escape($bean->{$idfield}); } try { $this->adapter->exec($sql); } catch (RedBean_Exception_SQL $e) { if ($e->getSQLState() != "42S02" && $e->getSQLState() != "42S22") { throw $e; } } }
/** * Converts a series of rows to beans. * @param string $type * @param array $rows must contain an array of arrays. * @return array $beans */ public static function convertToBeans($type, $rows) { return self::$redbean->convertToBeans($type, $rows); }
/** * Constructor, * creates a new instance of DupManager. * * @param RedBean_Toolbox $toolbox */ public function __construct(RedBean_Toolbox $toolbox) { $this->toolbox = $toolbox; $this->redbean = $toolbox->getRedBean(); $this->associationManager = $this->redbean->getAssociationManager(); }
/** * Sets a list of dependencies. * A dependency list contains an entry for each dependent bean. * A dependent bean will be removed if the relation with one of the * dependencies gets broken. * * Example: * * array( * 'page' => array('book','magazine') * ) * * A page will be removed if: * * unset($book->ownPage[$pageID]); * * or: * * unset($magazine->ownPage[$pageID]); * * but not if: * * unset($paper->ownPage[$pageID]); * * * @param array $dep list of dependencies */ public static function dependencies($dep) { self::$redbean->setDepList($dep); }
/** * Deletes the inner bean from the database. */ public function delete() { $this->redbean->trash($this->bean); }
/** * Nukes the entire database. */ public static function nuke() { if (!self::$redbean->isFrozen()) { self::$writer->wipeAll(); } }
/** * Test the database driver and low level functions. * * @return void */ public function testDriver() { $currentDriver = $this->currentlyActiveDriverID; R::store(R::dispense('justabean')); $adapter = new TroubleDapter(R::$toolbox->getDatabaseAdapter()->getDatabase()); $adapter->setSQLState('HY000'); $writer = new RedBean_QueryWriter_SQLiteT($adapter); $redbean = new RedBean_OODB($writer); $toolbox = new RedBean_ToolBox($redbean, $adapter, $writer); // We can only test this for a known driver... if ($currentDriver === 'sqlite') { try { $redbean->find('bean'); pass(); } catch (Exception $e) { var_dump($e->getSQLState()); fail(); } } $adapter->setSQLState(-999); try { $redbean->find('bean'); fail(); } catch (Exception $e) { pass(); } $beanA = R::dispense('bean'); $beanB = R::dispense('bean'); R::storeAll(array($beanA, $beanB)); $associationManager = new RedBean_AssociationManager($toolbox); $adapter->setSQLState('HY000'); // We can only test this for a known driver... if ($currentDriver === 'sqlite') { try { $associationManager->areRelated($beanA, $beanB); pass(); } catch (Exception $e) { fail(); } } $adapter->setSQLState(-999); try { $associationManager->areRelated($beanA, $beanA); fail(); } catch (Exception $e) { pass(); } try { $redbean->wipe('justabean'); fail(); } catch (Exception $e) { pass(); } $toolbox = R::$toolbox; $adapter = $toolbox->getDatabaseAdapter(); $writer = $toolbox->getWriter(); $redbean = $toolbox->getRedBean(); $pdo = $adapter->getDatabase(); $page = $redbean->dispense("page"); try { $adapter->exec("an invalid query"); fail(); } catch (RedBean_Exception_SQL $e) { pass(); } // Special data type description should result in magic number 99 (specified) if ($currentDriver == 'mysql') { asrt($writer->code(RedBean_QueryWriter_MySQL::C_DATATYPE_SPECIAL_DATE), 99); } if ($currentDriver == 'pgsql') { asrt($writer->code(RedBean_QueryWriter_PostgreSQL::C_DATATYPE_SPECIAL_DATE), 99); } if ($currentDriver == 'CUBRID') { asrt($writer->code(RedBean_QueryWriter_CUBRID::C_DATATYPE_SPECIAL_DATE), 99); } asrt((int) $adapter->getCell("SELECT 123"), 123); $page->aname = "my page"; $id = (int) $redbean->store($page); asrt((int) $page->id, 1); asrt((int) $pdo->GetCell("SELECT count(*) FROM page"), 1); asrt($pdo->GetCell("SELECT aname FROM page LIMIT 1"), "my page"); asrt((int) $id, 1); $page = $redbean->load("page", 1); asrt($page->aname, "my page"); asrt((bool) $page->getMeta("type"), TRUE); asrt(isset($page->id), TRUE); asrt($page->getMeta("type"), "page"); asrt((int) $page->id, $id); }
public function getParent(RedBean_OODBBean $bean) { return $this->oodb->load($bean->getMeta("type"), (int) $bean->parent_id); }
$g->type = "merlot"; $b->texture = "wood"; $a->associate($g, $b); $a = new RedBean_AssociationManager($toolbox); $writer = $oldwriter; $redbean = $oldredbean; testpack("Test Custom ID Field"); class MyWriter extends RedBean_QueryWriter_PostgreSQL { public function getIDField($type) { return $type . "_id"; } } $writer2 = new MyWriter($adapter); $redbean2 = new RedBean_OODB($writer2); $movie = $redbean2->dispense("movie"); asrt(isset($movie->movie_id), true); $movie->name = "movie 1"; $movieid = $redbean2->store($movie); asrt($movieid > 0, true); $columns = array_keys($writer->getColumns("movie")); asrt(in_array("movie_id", $columns), true); asrt(in_array("id", $columns), false); $movie2 = $redbean2->dispense("movie"); asrt(isset($movie2->movie_id), true); $movie2->name = "movie 2"; $movieid2 = $redbean2->store($movie2); $movie1 = $redbean2->load("movie", $movieid); asrt($movie->name, "movie 1"); $movie2 = $redbean2->load("movie", $movieid2);
public static function kickstart($dsn, $username = NULL, $password = NULL, $frozen = false) { if ($dsn instanceof PDO) { $pdo = new RedBean_Driver_PDO($dsn); $dsn = $pdo->getDatabaseType(); } else { self::checkDSN($dsn); $pdo = new RedBean_Driver_PDO($dsn, $username, $password); } $adapter = new RedBean_Adapter_DBAdapter($pdo); if (strpos($dsn, "pgsql") === 0) { $writer = new RedBean_QueryWriter_PostgreSQL($adapter); } else { if (strpos($dsn, "sqlite") === 0) { $writer = new RedBean_QueryWriter_SQLiteT($adapter); } else { $writer = new RedBean_QueryWriter_MySQL($adapter); } } $redbean = new RedBean_OODB($writer); if ($frozen) { $redbean->freeze(true); } $toolbox = new RedBean_ToolBox($redbean, $adapter, $writer); self::$toolbox = $toolbox; return self::$toolbox; }
/** * Preloads certain properties for beans. * Understands aliases. * * Usage: * * $db->preload($books, 'author'); * * - preloads all the authors of all books, * saves you a query per for-each iteration * * $db->preload($books, array('coauthor'=>'author')); * * - same but with alias * * $db->preload($texts,'page,page.book,page.book.author'); * * - preloads all pages for the texts, the books and the authors * * $db->preload($texts,'page,*.book,*.author'); * * - same as above bit with short syntax (* means prefix with previous types) * * $db->preload($p,'book,*.author,&.shelf'); * * - if author and shelf are on the same level use & instead of *. * * The other way around is possible as well, to load child beans in own-lists or * shared-lists use: * * $db->preload($books,'ownPage|page,sharedGenre|genre'); * * @param array $beans beans beans to use as a reference for preloading * @param array|string $types types to load, either string or array * * @return array */ public function preload($beans, $types, $closure = NULL) { return $this->redbean->preload($beans, $types, $closure); }
/** * Trashes a RedBean OODBBean and removes it from cache. * * @param RedBean_OODBBean $bean bean * @return mixed */ public function trash($bean) { $type = $bean->getMeta('type'); $id = $bean->id; if (isset($this->cache[$type][$id])) { unset($this->cache[$type][$id]); } return parent::trash($bean); }
/** * @see RedBean_DuplicationManager::dup * * @param RedBean_OODBBean $bean bean to be copied * @param array $trail trail to prevent infinite loops * @param boolean $pid preserve IDs * * @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->importFrom($bean); $copy->id = 0; $tables = $this->tables; foreach ($tables as $table) { if (is_array($this->filters) && count($this->filters) && !in_array($table, $this->filters)) { continue; } if ($table == $type) { continue; } $owned = 'own' . ucfirst($table); $shared = 'shared' . ucfirst($table); if ($this->hasSharedList($type, $table)) { if ($beans = $bean->{$shared}) { $copy->{$shared} = array(); foreach ($beans as $subBean) { array_push($copy->{$shared}, $subBean); } } } elseif ($this->hasOwnList($type, $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); } $copy->setMeta('sys.shadow.' . $shared, null); } if ($pid) { $copy->id = $bean->id; } return $copy; }
/** * Preloads certain properties for beans. * Understands aliases. * * Usage: * * R::preload($books, 'author'); * * - preloads all the authors of all books, * saves you a query per for-each iteration * * R::preload($books, array('coauthor'=>'author')); * * - same but with alias * * R::preload($texts,'page,page.book,page.book.author'); * * - preloads all pages for the texts, the books and the authors * * R::preload($texts,'page,*.book,*.author'); * * - same as above bit with short syntax (* means prefix with previous types) * * R::preload($p,'book,*.author,&.shelf'); * * - if author and shelf are on the same level use & instead of *. * * The other way around is possible as well, to load child beans in own-lists or * shared-lists use: * * R::preload($books,'ownPage|page,sharedGenre|genre'); * * @param array $beans beans beans to use as a reference for preloading * @param array|string $types types to load, either string or array * * @return array */ public static function preload($beans, $types, $closure = NULL) { return self::$redbean->preload($beans, $types, $closure); }
/** * Closes and unlocks the bean * @param $deco * @return unknown_type */ public static function close($deco) { RedBean_OODB::closeBean($deco->getData()); }
/** * Loads the Bean internally * @param integer $id */ public function find($id) { $this->bean = $this->redbean->load($this->bean->getMeta("type"), (int) $id); }
/** * 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. * * @static * @param RedBean_ToolBox $tb toolbox * * @return RedBean_ToolBox $tb old, rusty, previously used toolbox */ public static function configureFacadeWithToolbox( RedBean_ToolBox $tb ) { $oldTools = self::$toolbox; self::$toolbox = $tb; self::$writer = self::$toolbox->getWriter(); self::$adapter = self::$toolbox->getDatabaseAdapter(); self::$redbean = self::$toolbox->getRedBean(); self::$associationManager = new RedBean_AssociationManager( self::$toolbox ); self::$treeManager = new RedBean_TreeManager( self::$toolbox ); self::$linkManager = new RedBean_LinkManager( self::$toolbox ); self::$extAssocManager = new RedBean_ExtAssociationManager( self::$toolbox ); $helper = new RedBean_ModelHelper(); self::$redbean->addEventListener("update", $helper ); self::$redbean->addEventListener("open", $helper ); self::$redbean->addEventListener("delete", $helper ); self::$redbean->addEventListener("after_delete", $helper ); self::$redbean->addEventListener("after_update", $helper ); self::$redbean->addEventListener("dispense", $helper ); return $oldTools; }