public function countRelated(One_Relation_Adapter $link, One_Model $model, array $options = array()) { $linkName = $link->getName(); // identify the target scheme $source = One_Repository::getScheme($model->getSchemeName()); $target = One_Repository::getScheme($link->getTarget()); $backlinks = $target->getLinks(); $backlink = $backlinks[$link->getLinkId()]; if (!$backlink) { throw new One_Exception('The role "' . $roleName . '" does not exist for this model'); } $at = $source->getIdentityAttribute()->getName(); $column = $this->remoteFK($link, $source, $backlink); // bind the data using the data $localValue = $model->{$at}; // create query and execute $q = One_Repository::selectQuery($link->getTarget()); $q->setOptions($options); if (isset($link->meta['hybrid'])) { $var = $link->meta['hybrid'] . '_scheme'; $q->where($var, 'eq', $source->getName()); } $q->where($column, 'eq', $localValue); return $q->getCount(); }
/** * find out what the scheme's FK field for this relationship is called. * By default, this is formed by * ROLENAME_NAMEOFTARGETIDCOLUMN, * but this can be overridden by the FK setting in the meta description. * * @param One_Relation_Adapter $adapter * @param One_Scheme $source * @param One_Relation_Adapter $backlink * @return string */ public function remoteFK(One_Relation_Adapter $adapter, One_Scheme $source, One_Relation_Adapter $backlink) { if ($adapter->meta['fk:remote']) { return $adapter->meta['fk:remote']; } $column = $source->getIdentityAttribute()->getName(); return $backlink->getName() . "_" . $column; }
public function countRelated(One_Relation_Adapter $link, One_Model $model, array $options = array()) { $linkName = $link->getName(); // identify the target scheme $source = One_Repository::getScheme($model->getSchemeName()); // PD 22OCT08 if ($link->getTarget() == '*') { $col = $link->getName() . '_scheme'; $target = One_Repository::getScheme($model->{$col}); } else { $target = One_Repository::getScheme($link->getTarget()); } // determine the target's identity column $column = $this->localFK($link, $target); // bind the data using the data $localValue = $model[$column]; // create query and execute return One_Repository::selectOne($target->getName(), $localValue) ? 1 : 0; }
/** * Delete a relationship from the model * * @param One_Model $model * @param One_Relation_Adapter $link */ public function deleteRelations(One_Model $model, One_Relation_Adapter $link) { $deleted = $model->getDeletedRelations(); if (isset($deleted[$link->getName()])) { // @todo - this probably isn't the correct way to get to the db object we need? // the db object should be based on the info in the $link, not the $model ... $scheme = One_Repository::getScheme($model->getSchemeName()); $db = $this->db($scheme); $table = $link->meta['table']; $localKey = $link->fk('local'); $remoteKey = $link->fk('remote'); $localId = $model->getIdentityName(); $localValue = $model->{$localId}; // Insert the new (modified) relations in the given model $values = array(); foreach ($deleted[$link->getName()] as $remoteValue) { if (is_array($remoteValue)) { foreach ($remoteValue as $rVal) { $values[] = '`' . $remoteKey . '` = "' . mysql_real_escape_string($rVal, $db) . '"'; } } else { $values[] = '`' . $remoteKey . '` = "' . mysql_real_escape_string($remoteValue, $db) . '"'; } } // only run the insert query if we actually received new values if (count($values)) { $sql = 'DELETE FROM `' . $table . '` ' . 'WHERE `' . $localKey . '` = "' . mysql_real_escape_string($localValue, $db) . '"' . 'AND ( ' . implode(' OR ', $values) . ' )'; mysql_query($sql, $db); } } }
/** * Add a link to the scheme * * @param One_Relation_Adapter $link */ public function addLink(One_Relation_Adapter $link) { $this->_links[$link->getName()] = $link; $this->_linksById[$link->getLinkId()] = $link; if ($link->getAdapterType() instanceof One_Relation_Adapter_Manytoone) { if (null !== $link->getForeignKey()) { $this->_foreignKeys[] = $link->getForeignKey(); } } }
/** * Saves all "many-to-many" and "one-to-many"-relations * * @param One_Relation_Adapter $link * @return void */ public function saveRelated(One_Relation_Adapter $link) { if (array_key_exists($link->getName(), $this->_modifiedRelations) && $link->getAdapterType() != "manytoone") { $link->save($this); } if (array_key_exists($link->getName(), $this->_addedRelations) && $link->getAdapterType() != "manytoone") { $link->add($this); } if (array_key_exists($link->getName(), $this->_deletedRelations) && $link->getAdapterType() != "manytoone") { $link->remove($this); } }
public function countRelated(One_Relation_Adapter $link, One_Model $model, array $options = array()) { $nRelated = 0; $linkName = $link->getName(); // identify the target scheme $source = One_Repository::getScheme($model->getSchemeName()); $target = One_Repository::getScheme($link->getTarget()); $backlinks = $target->getLinks(); $backlink = $backlinks[$link->getLinkId()]; if (!$backlink) { throw new One_Exception("There is no link with id " . $link->getLinkId() . " in scheme " . $link->getTarget()); } $sourceId = $source->getIdentityAttribute()->getName(); $localValue = $model[$sourceId]; $targetId = $target->getIdentityAttribute()->getName(); // TR20100615 if all stores are equal, do normal join, if not, fetch data in several steps // @TODO This should actually be handled in One_Query if ($source->getConnection()->getName() == $link->meta['connection'] && $link->meta['connection'] == $target->getConnection()->getName()) { $lQ = One_Repository::selectQuery($source); $lQ->setSelect(array($linkName . ':*')); $lQ->where($sourceId, 'eq', $localValue); if (array_key_exists('query', $options) && is_array($options['query']) && count($options['query']) > 0) { foreach ($options['query'] as $qKey => $qOption) { if (count($qOption) == 3) { $options['query'][$qKey][0] = $linkName . ':' . $options['query'][$qKey][0]; } } } $lQ->setOptions($options); $nRelated = $lQ->getCount(); } else { $fkLocal = $link->meta['fk:local']; $fkRemote = $link->meta['fk:remote']; $omtms = One_Repository::getScheme('onemanytomany'); $omtms->setConnection(One_Repository::getConnection($link->meta['connection'])); $omtms->setResources($link->meta); $localAtt = new One_Scheme_Attribute($fkLocal, $source->getIdentityAttribute()->getType()->getName()); $remoteAtt = new One_Scheme_Attribute($fkRemote, $target->getIdentityAttribute()->getType()->getName()); $omtms->addAttribute($localAtt); $omtms->addAttribute($remoteAtt); $joinQ = One_Repository::selectQuery($omtms); $joinQ->setSelect(array($fkRemote)); $joinQ->where($fkLocal, 'eq', $localValue); $rawRelatedIDs = $joinQ->execute(false); $related = array(); if (count($rawRelatedIDs) > 0) { $relatedIDs = array(); foreach ($rawRelatedIDs as $row) { $relatedIDs[] = $row->{$fkRemote}; } $lQ = One_Repository::selectQuery($target); $lQ->where($targetId, 'in', $relatedIDs); $lQ->setOptions($options); $nRelated = $lQ->getCount(); } } return $nRelated; }