X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=classes%2FManaged_DataObject.php;h=0857bb11f6c277612b69f809c749c93acd61400a;hb=a2d8305e2159f60df979898983b5fe4ccf166a16;hp=ec514029939547997f5e098925e79816868d0034;hpb=f7769c17b50356cce2172226ea10bd3355d14af1;p=quix0rs-gnu-social.git diff --git a/classes/Managed_DataObject.php b/classes/Managed_DataObject.php index ec51402993..0857bb11f6 100644 --- a/classes/Managed_DataObject.php +++ b/classes/Managed_DataObject.php @@ -334,7 +334,7 @@ abstract class Managed_DataObject extends Memcached_DataObject $object = new $classname(); foreach ($pkey as $col) { if (!array_key_exists($col, $vals)) { - throw new ServerException("Missing primary key column '{$col}'"); + throw new ServerException("Missing primary key column '{$col}' for ".get_called_class()." among provided keys: ".implode(',', array_keys($vals))); } elseif (is_null($vals[$col])) { throw new ServerException("NULL values not allowed in getByPK for column '{$col}'"); } @@ -346,10 +346,45 @@ abstract class Managed_DataObject extends Memcached_DataObject return $object; } + /** + * Returns an object by looking at given unique key columns. + * + * Will NOT accept NULL values for a unique key column. Ignores non-key values. + * + * @param array $vals All array keys which are set must be non-null. + * + * @return Managed_DataObject of the get_called_class() type + * @throws NoResultException if no object with that primary key + */ + static function getByKeys(array $vals) + { + $classname = get_called_class(); + + $object = new $classname(); + + $keys = $object->keys(); + if (is_null($keys)) { + throw new ServerException("Failed to get key columns for class '{$classname}'"); + } + + foreach ($keys as $col) { + if (!array_key_exists($col, $vals)) { + continue; + } elseif (is_null($vals[$col])) { + throw new ServerException("NULL values not allowed in getByKeys for column '{$col}'"); + } + $object->$col = $vals[$col]; + } + if (!$object->find(true)) { + throw new NoResultException($object); + } + return $object; + } + static function getByID($id) { if (empty($id)) { - throw new ServerException('Empty ID on lookup'); + throw new EmptyIdException(get_called_class()); } // getByPK throws exception if id is null // or if the class does not have a single 'id' column as primary key @@ -374,8 +409,61 @@ abstract class Managed_DataObject extends Memcached_DataObject throw new Exception('Empty ID for object! (not inserted yet?).'); } - // FIXME: How about forcing to return an int? Or will that overflow eventually? - return $this->id; + return intval($this->id); + } + + /** + * WARNING: Only use this on Profile and Notice. We should probably do + * this with traits/"implements" or whatever, but that's over the top + * right now, I'm just throwing this in here to avoid code duplication + * in Profile and Notice classes. + */ + public function getAliases() + { + return array_keys($this->getAliasesWithIDs()); + } + + public function getAliasesWithIDs() + { + $aliases = array(); + $aliases[$this->getUri()] = $this->getID(); + + try { + $aliases[$this->getUrl()] = $this->getID(); + } catch (InvalidUrlException $e) { + // getUrl failed because no valid URL could be returned, just ignore it + } + + if (common_config('fix', 'fancyurls')) { + /** + * Here we add some hacky hotfixes for remote lookups that have been taught the + * (at least now) wrong URI but it's still obviously the same user. Such as: + * - https://site.example/user/1 even if the client requests https://site.example/index.php/user/1 + * - https://site.example/user/1 even if the client requests https://site.example//index.php/user/1 + * - https://site.example/index.php/user/1 even if the client requests https://site.example/user/1 + * - https://site.example/index.php/user/1 even if the client requests https://site.example///index.php/user/1 + */ + foreach ($aliases as $alias=>$id) { + try { + // get a "fancy url" version of the alias, even without index.php/ + $alt_url = common_fake_local_fancy_url($alias); + // store this as well so remote sites can be sure we really are the same profile + $aliases[$alt_url] = $id; + } catch (Exception $e) { + // Apparently we couldn't rewrite that, the $alias was as the function wanted it to be + } + + try { + // get a non-"fancy url" version of the alias, i.e. add index.php/ + $alt_url = common_fake_local_nonfancy_url($alias); + // store this as well so remote sites can be sure we really are the same profile + $aliases[$alt_url] = $id; + } catch (Exception $e) { + // Apparently we couldn't rewrite that, the $alias was as the function wanted it to be + } + } + } + return $aliases; } // 'update' won't write key columns, so we have to do it ourselves. @@ -385,12 +473,16 @@ abstract class Managed_DataObject extends Memcached_DataObject * @param DB_DataObject &$orig Must be "instanceof" $this * @param string $pid Primary ID column (no escaping is done on column name!) */ - public function updateWithKeys(&$orig, $pid='id') + public function updateWithKeys(Managed_DataObject $orig, $pid=null) { if (!$orig instanceof $this) { throw new ServerException('Tried updating a DataObject with a different class than itself.'); } + if ($this->N <1) { + throw new ServerException('DataObject must be the result of a query (N>=1) before updateWithKeys()'); + } + // do it in a transaction $this->query('BEGIN'); @@ -417,11 +509,23 @@ abstract class Managed_DataObject extends Memcached_DataObject return true; } - $qry = sprintf('UPDATE %1$s SET %2$s WHERE %3$s = %4$s', + if ($pid === null) { + $schema = static::schemaDef(); + $pid = $schema['primary key']; + unset($schema); + } + $pidWhere = array(); + foreach((array)$pid as $pidCol) { + $pidWhere[] = sprintf('%1$s = %2$s', $pidCol, $this->_quote($orig->$pidCol)); + } + if (empty($pidWhere)) { + throw new ServerException('No primary ID column(s) set for updateWithKeys'); + } + + $qry = sprintf('UPDATE %1$s SET %2$s WHERE %3$s', common_database_tablename($this->tableName()), implode(', ', $parts), - $pid, - $this->_quote($this->$pid)); + implode(' AND ', $pidWhere)); $result = $this->query($qry); if ($result === false) { @@ -453,4 +557,38 @@ abstract class Managed_DataObject extends Memcached_DataObject { // NOOP } + + static function newUri(Profile $actor, Managed_DataObject $object, $created=null) + { + if (is_null($created)) { + $created = common_sql_now(); + } + return TagURI::mint(strtolower(get_called_class()).':%d:%s:%d:%s', + $actor->getID(), + ActivityUtils::resolveUri($object->getObjectType(), true), + $object->getID(), + common_date_iso8601($created)); + } + + protected function onInsert() + { + // NOOP by default + } + + protected function onUpdate($dataObject=false) + { + // NOOP by default + } + + public function insert() + { + $this->onInsert(); + return parent::insert(); + } + + public function update($dataObject=false) + { + $this->onUpdate($dataObject); + return parent::update($dataObject); + } }