Пример #1
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();
 }
Пример #2
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;
 }
Пример #3
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;
 }
Пример #4
0
 public function areRelated(RedBean_OODBBean $bean1, RedBean_OODBBean $bean2)
 {
     if (!$bean1->getID() || !$bean2->getID()) {
         return false;
     }
     $table = $this->getTable(array($bean1->getMeta("type"), $bean2->getMeta("type")));
     $idfield1 = $this->writer->getIDField($bean1->getMeta("type"));
     $idfield2 = $this->writer->getIDField($bean2->getMeta("type"));
     $type = $bean1->getMeta("type");
     if ($type == $bean2->getMeta("type")) {
         $type .= "2";
         $cross = 1;
     } else {
         $cross = 0;
     }
     $property1 = $type . "_id";
     $property2 = $bean2->getMeta("type") . "_id";
     $value1 = (int) $bean1->{$idfield1};
     $value2 = (int) $bean2->{$idfield2};
     try {
         $rows = $this->writer->selectRecord($table, array($property1 => array($value1), $property2 => array($value2)), null);
         if ($cross) {
             $rows2 = $this->writer->selectRecord($table, array($property2 => array($value1), $property1 => array($value2)), null);
             $rows = array_merge($rows, $rows2);
         }
     } 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;
         }
         return false;
     }
     return count($rows) > 0;
 }
Пример #5
0
 /**
  * @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;
 }
Пример #6
0
 public function exportBean(RedBean_OODBBean $bean)
 {
     $bid = $bean->getMeta('type') . '-' . $bean->getID();
     if (isset($this->recurCheck[$bid])) {
         return null;
     }
     $this->recurCheck[$bid] = $bid;
     $export = $bean->export();
     foreach ($export as $key => $value) {
         if (strpos($key, '_id') !== false) {
             $sub = str_replace('_id', '', $key);
             $subBean = $bean->{$sub};
             if ($subBean) {
                 $export[$sub] = $this->export($subBean, false);
             }
         }
     }
     $type = $bean->getMeta('type');
     $linkField = $type . '_id';
     foreach ($this->tables as $table => $cols) {
         if (strpos($table, '_') === false) {
             if (in_array($linkField, array_keys($cols))) {
                 $field = 'own' . ucfirst($table);
                 $export[$field] = self::export($bean->{$field}, false);
             }
         }
     }
     foreach ($this->tables as $table => $cols) {
         if (strpos($table, '_') !== false) {
             $parts = explode('_', $table);
             if (is_array($parts) && in_array($type, $parts)) {
                 $other = $parts[0];
                 if ($other == $type) {
                     $other = $parts[1];
                 }
                 $field = 'shared' . ucfirst($other);
                 $export[$field] = self::export($bean->{$field}, false);
             }
         }
     }
     return $export;
 }
Пример #7
0
 /**
  * Exports a single bean
  *
  * @param RedBean_OODBBean $bean Bean to be exported
  *
  * @return array|NULL $array Array export of bean
  */
 public function exportBean(RedBean_OODBBean $bean)
 {
     $bid = $bean->getMeta('type') . '-' . $bean->getID();
     if (isset($this->recurCheck[$bid])) {
         return NULL;
     }
     $this->recurCheck[$bid] = $bid;
     $export = $bean->export();
     foreach ($export as $key => $value) {
         $this->extractParentBean($export, $bean, $key, $value);
     }
     foreach ($this->tables as $table => $cols) {
         //get all ownProperties
         $this->extractOwnList($export, $bean, $table, $cols);
     }
     foreach ($this->tables as $table => $cols) {
         //get all sharedProperties
         $this->extractSharedList($export, $bean, $table);
     }
     return $export;
 }
Пример #8
0
 /**
  * Stores a bean in the database. This function takes a
  * RedBean_OODBBean Bean Object $bean and stores it
  * in the database. If the database schema is not compatible
  * with this bean and RedBean runs in fluid mode the schema
  * will be altered to store the bean correctly.
  * If the database schema is not compatible with this bean and
  * RedBean runs in frozen mode it will throw an exception.
  * This function returns the primary key ID of the inserted
  * bean.
  *
  * @throws RedBean_Exception_Security $exception
  * @param RedBean_OODBBean $bean bean to store
  *
  * @return integer $newid
  */
 public function store(RedBean_OODBBean $bean)
 {
     $processLists = false;
     foreach ($bean as $k => $v) {
         if (is_array($v) || is_object($v)) {
             $processLists = true;
             break;
         }
     }
     if (!$processLists && !$bean->getMeta('tainted')) {
         return $bean->getID();
     }
     $this->signal("update", $bean);
     if ($processLists) {
         //Define groups
         $sharedAdditions = $sharedTrashcan = $sharedresidue = $sharedItems = array();
         $ownAdditions = $ownTrashcan = $ownresidue = array();
         $tmpCollectionStore = array();
         $embeddedBeans = array();
         foreach ($bean as $p => $v) {
             if ($v instanceof RedBean_OODBBean) {
                 $embtype = $v->getMeta('type');
                 $idfield = $this->writer->getIDField($embtype);
                 if (!$v->{$idfield} || $v->getMeta('tainted')) {
                     $this->store($v);
                 }
                 $beanID = $v->{$idfield};
                 $linkField = $p . '_id';
                 $bean->{$linkField} = $beanID;
                 $bean->setMeta('cast.' . $linkField, 'id');
                 $embeddedBeans[$linkField] = $v;
                 $tmpCollectionStore[$p] = $bean->{$p};
                 $bean->removeProperty($p);
             }
             if (is_array($v)) {
                 $originals = $bean->getMeta('sys.shadow.' . $p);
                 if (!$originals) {
                     $originals = array();
                 }
                 if (strpos($p, 'own') === 0) {
                     list($ownAdditions, $ownTrashcan, $ownresidue) = $this->processGroups($originals, $v, $ownAdditions, $ownTrashcan, $ownresidue);
                     $bean->removeProperty($p);
                 } elseif (strpos($p, 'shared') === 0) {
                     list($sharedAdditions, $sharedTrashcan, $sharedresidue) = $this->processGroups($originals, $v, $sharedAdditions, $sharedTrashcan, $sharedresidue);
                     $bean->removeProperty($p);
                 } else {
                 }
             }
         }
     }
     if (!$this->isFrozen) {
         $this->check($bean);
     }
     //what table does it want
     $table = $bean->getMeta("type");
     $idfield = $this->writer->getIDField($table);
     if ($bean->getMeta('tainted')) {
         //Does table exist? If not, create
         if (!$this->isFrozen && !$this->tableExists($table)) {
             $this->writer->createTable($table);
             $bean->setMeta("buildreport.flags.created", true);
         }
         if (!$this->isFrozen) {
             $columns = $this->writer->getColumns($table);
         }
         //does the table fit?
         $insertvalues = array();
         $insertcolumns = array();
         $updatevalues = array();
         foreach ($bean as $p => $v) {
             if ($p != $idfield) {
                 if (!$this->isFrozen) {
                     //Does the user want to specify the type?
                     if ($bean->getMeta("cast.{$p}", -1) !== -1) {
                         $cast = $bean->getMeta("cast.{$p}");
                         if ($cast == "string") {
                             $typeno = $this->writer->scanType("STRING");
                         } elseif ($cast == "id") {
                             $typeno = $this->writer->getTypeForID();
                         } else {
                             throw new RedBean_Exception("Invalid Cast");
                         }
                     } else {
                         //What kind of property are we dealing with?
                         $typeno = $this->writer->scanType($v);
                     }
                     //Is this property represented in the table?
                     if (isset($columns[$p])) {
                         //yes it is, does it still fit?
                         $sqlt = $this->writer->code($columns[$p]);
                         if ($typeno > $sqlt) {
                             //no, we have to widen the database column type
                             $this->writer->widenColumn($table, $p, $typeno);
                             $bean->setMeta("buildreport.flags.widen", true);
                         }
                     } else {
                         //no it is not
                         $this->writer->addColumn($table, $p, $typeno);
                         $bean->setMeta("buildreport.flags.addcolumn", true);
                         //@todo: move build commands here... more practical
                         $this->processBuildCommands($table, $p, $bean);
                     }
                 }
                 //Okay, now we are sure that the property value will fit
                 $insertvalues[] = $v;
                 $insertcolumns[] = $p;
                 $updatevalues[] = array("property" => $p, "value" => $v);
             }
         }
         if (!$this->isFrozen && ($uniques = $bean->getMeta("buildcommand.unique"))) {
             foreach ($uniques as $unique) {
                 $this->writer->addUniqueIndex($table, $unique);
             }
         }
         $rs = $this->writer->updateRecord($table, $updatevalues, $bean->{$idfield});
         $bean->{$idfield} = $rs;
         $bean->setMeta("tainted", false);
     }
     if ($processLists) {
         foreach ($embeddedBeans as $linkField => $embeddedBean) {
             if (!$this->isFrozen) {
                 $this->writer->addIndex($bean->getMeta('type'), 'index_foreignkey_' . $embeddedBean->getMeta('type'), $linkField);
                 $this->writer->addFK($bean->getMeta('type'), $embeddedBean->getMeta('type'), $linkField, $this->writer->getIDField($embeddedBean->getMeta('type')));
             }
         }
         $myFieldLink = $bean->getMeta('type') . '_id';
         //Handle related beans
         foreach ($ownTrashcan as $trash) {
             if ($trash instanceof RedBean_OODBBean) {
                 $trash->{$myFieldLink} = null;
                 $this->store($trash);
             } else {
                 throw new RedBean_Exception_Security('Array may only contain RedBean_OODBBeans');
             }
         }
         foreach ($ownAdditions as $addition) {
             if ($addition instanceof RedBean_OODBBean) {
                 $addition->{$myFieldLink} = $bean->{$idfield};
                 $addition->setMeta('cast.' . $myFieldLink, 'id');
                 $this->store($addition);
                 if (!$this->isFrozen) {
                     $this->writer->addIndex($addition->getMeta('type'), 'index_foreignkey_' . $bean->getMeta('type'), $myFieldLink);
                     $this->writer->addFK($addition->getMeta('type'), $bean->getMeta('type'), $myFieldLink, $idfield);
                 }
             } else {
                 throw new RedBean_Exception_Security('Array may only contain RedBean_OODBBeans');
             }
         }
         foreach ($ownresidue as $residue) {
             if ($residue instanceof RedBean_OODBBean) {
                 if ($residue->getMeta('tainted')) {
                     $this->store($residue);
                 }
             } else {
                 throw new RedBean_Exception_Security('Array may only contain RedBean_OODBBeans');
             }
         }
         foreach ($sharedTrashcan as $trash) {
             if ($trash instanceof RedBean_OODBBean) {
                 $this->assocManager->unassociate($trash, $bean);
             } else {
                 throw new RedBean_Exception_Security('Array may only contain RedBean_OODBBeans');
             }
         }
         foreach ($sharedAdditions as $addition) {
             if ($addition instanceof RedBean_OODBBean) {
                 $this->assocManager->associate($addition, $bean);
             } else {
                 throw new RedBean_Exception_Security('Array may only contain RedBean_OODBBeans');
             }
         }
         foreach ($sharedresidue as $residue) {
             if ($residue instanceof RedBean_OODBBean) {
                 $this->store($residue);
             } else {
                 throw new RedBean_Exception_Security('Array may only contain RedBean_OODBBeans');
             }
         }
     }
     $this->signal("after_update", $bean);
     return (int) $bean->{$idfield};
 }