Esempio n. 1
0
 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();
 }
Esempio n. 2
0
 /**
  *  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;
 }
Esempio n. 3
0
 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;
 }
Esempio n. 4
0
 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;
 }
Esempio n. 5
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);
         }
     }
 }
Esempio n. 6
0
 /**
  * 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();
         }
     }
 }
Esempio n. 7
0
 /**
  * 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);
     }
 }