/** * Save a relationship of the model * * @param One_Model $model * @param One_Relation_Adapter $link */ public function saveRelations(One_Model $model, One_Relation_Adapter $link) { $modified = $model->getModifiedRelations(); if (isset($modified[$link->getName()])) { $linkConnection = One_Repository::getConnection($link->meta['connection']); if (!$linkConnection->getStore() instanceof One_Store_Mysql) { $linkConnection->getStore()->saveRelations($model, $link); } else { $db = $this->dbFromConnection($linkConnection); $table = $link->meta['table']; $localKey = $link->fk('local'); $remoteKey = $link->fk('remote'); $localId = $model->getIdentityName(); $localValue = $model->{$localId}; // Start by removing the old relations between these models $sql = 'DELETE FROM `' . $table . '` ' . 'WHERE `' . $localKey . '` = "' . mysql_real_escape_string($localValue, $db) . '"'; mysql_query($sql, $db); // Insert the new (modified) relations in the given model $values = array(); foreach ($modified[$link->getName()] as $remoteValue) { $values[] = '( "' . mysql_real_escape_string($localValue, $db) . '", "' . mysql_real_escape_string($remoteValue, $db) . '") '; } // only run the insert query if we actually received new values if (count($values)) { $sql = 'INSERT INTO `' . $table . '` (`' . $localKey . '`, `' . $remoteKey . '`) ' . 'VALUES ' . implode(", ", $values); mysql_query($sql, $db); } } } }
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; }
/** * Remove a relation from the link * * @param mixed $model Can be One_Model or array of One_Models */ public function remove($model) { $connectionName = $this->meta['connection']; $connection = One_Repository::getConnection($connectionName); $store = $connection->getStore(); $store->deleteRelations($model, $this); }
/** * Set the One_Store used for the scheme * * @param One_Scheme $scheme * @param DOMXPath $xpath * @param DOMElement $meta */ protected static function setConnection(One_Scheme $scheme, DOMXPath $xpath, DOMElement $meta) { $connectionSpec = $xpath->query($meta->getNodePath() . '/connection'); if ($connectionSpec->length > 0) { $connection = $connectionSpec->item(0); $connectionName = trim($connection->getAttribute('name')); if ($connectionName != '') { $scheme->setConnection(One_Repository::getConnection($connectionName)); $connectionAtts = array(); $allAttributes = $connection->attributes; for ($i = 0; $i < $allAttributes->length; $i++) { $connectionAtt = $allAttributes->item($i); $connectionAtts[$connectionAtt->name] = $connectionAtt->value; } // Set resources as an array, because this is not necesarily the same for different stores // EG: mysql has a table attribute, SugarCRM has module $scheme->setResources($connectionAtts); } } }