/** * Iterates through the specified own-list and * fetches all properties (with their type) and * returns the references. * Use this method to quickly load indirectly related * beans in an own-list. Whenever you cannot use a * shared-list this method offers the same convenience * by aggregating the parent beans of all children in * the specified own-list. * * Example: * * <code> * $quest->aggr( 'xownQuestTarget', 'target', 'quest' ); * </code> * * Loads (in batch) and returns references to all * quest beans residing in the $questTarget->target properties * of each element in the xownQuestTargetList. * * @param string $list the list you wish to process * @param string $property the property to load * @param string $type the type of bean residing in this property (optional) * * @return array */ public function &aggr($list, $property, $type = NULL) { $this->via = NULL; $ids = $beanIndex = $references = array(); if (strlen($list) < 4) { throw new RedException('Invalid own-list.'); } if (strpos($list, 'own') !== 0) { throw new RedException('Only own-lists can be aggregated.'); } if (!ctype_upper(substr($list, 3, 1))) { throw new RedException('Invalid own-list.'); } if (is_null($type)) { $type = $property; } foreach ($this->{$list} as $bean) { $field = $property . '_id'; if (isset($bean->{$field})) { $ids[] = $bean->{$field}; $beanIndex[$bean->{$field}] = $bean; } } $beans = $this->beanHelper->getToolBox()->getRedBean()->batch($type, $ids); //now preload the beans as well foreach ($beans as $bean) { $beanIndex[$bean->id]->setProperty($property, $bean); } foreach ($beanIndex as $indexedBean) { $references[] = $indexedBean->{$property}; } return $references; }
/** * Creates a N-M relation by linking an intermediate bean. * This method can be used to quickly connect beans using indirect * relations. For instance, given an album and a song you can connect the two * using a track with a number like this: * * Usage: * * $album->link('track', array('number'=>1))->song = $song; * * or: * * $album->link($trackBean)->song = $song; * * What this method does is adding the link bean to the own-list, in this case * ownTrack. If the first argument is a string and the second is an array or * a JSON string then the linking bean gets dispensed on-the-fly as seen in * example #1. After preparing the linking bean, the bean is returned thus * allowing the chained setter: ->song = $song. * * @param string|OODBBean $type type of bean to dispense or the full bean * @param string|array $qualification JSON string or array (optional) * * @return OODBBean */ public function link($typeOrBean, $qualification = array()) { if (is_string($typeOrBean)) { $typeOrBean = AQueryWriter::camelsSnake($typeOrBean); $bean = $this->beanHelper->getToolBox()->getRedBean()->dispense($typeOrBean); if (is_string($qualification)) { $data = json_decode($qualification, TRUE); } else { $data = $qualification; } foreach ($data as $key => $value) { $bean->{$key} = $value; } } else { $bean = $typeOrBean; } $list = 'own' . ucfirst($bean->getMeta('type')); array_push($this->{$list}, $bean); return $bean; }