From: Mikael Nordfeldth Date: Sat, 6 May 2017 12:40:06 +0000 (+0200) Subject: Merge branch 'master' into mmn_fixes X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=4f37c564a5e1d7bb9babb202447057bb39bab175;p=quix0rs-gnu-social.git Merge branch 'master' into mmn_fixes --- 4f37c564a5e1d7bb9babb202447057bb39bab175 diff --cc classes/Notice.php index a8561948b4,1a7964fc06..b22b4296e0 --- a/classes/Notice.php +++ b/classes/Notice.php @@@ -1044,18 -1022,14 +1044,22 @@@ class Notice extends Managed_DataObjec throw $e; } } + unset($notloc); // garbage collect + if (!$stored instanceof Notice) { - throw new ServerException('StartNoticeSave did not give back a Notice'); + throw new ServerException('StartNoticeSave did not give back a Notice.'); + } elseif (empty($stored->id)) { + throw new ServerException('Supposedly saved Notice has no ID.'); + } + + if ($self && common_valid_http_url($self)) { + $stored->setPref('ostatus', 'self', $self); } + if ($self && common_valid_http_url($self)) { + $stored->setPref('ostatus', 'self', $self); + } + // Only save 'attention' and metadata stuff (URLs, tags...) stuff if // the activityverb is a POST (since stuff like repeat, favorite etc. // reasonably handle notifications themselves. @@@ -3131,136 -3083,65 +3135,159 @@@ // 2015-09-04 We move Notice location data to Notice_location // First we see if we have to do this at all - if (!isset($schemadef['fields']['lat']) - && !isset($schemadef['fields']['lon']) - && !isset($schemadef['fields']['location_id']) - && !isset($schemadef['fields']['location_ns'])) { - // We have already removed the location fields, so no need to migrate. - return; + if (isset($schemadef['fields']['lat']) + && isset($schemadef['fields']['lon']) + && isset($schemadef['fields']['location_id']) + && isset($schemadef['fields']['location_ns'])) { + // Then we make sure the Notice_location table is created! + $schema->ensureTable('notice_location', Notice_location::schemaDef()); + + // Then we continue on our road to migration! + echo "\nFound old $table table, moving location data to 'notice_location' table... (this will probably take a LONG time, but can be aborted and continued)"; + + $notice = new Notice(); + $notice->query(sprintf('SELECT id, lat, lon, location_id, location_ns FROM %1$s ' . + 'WHERE lat IS NOT NULL ' . + 'OR lon IS NOT NULL ' . + 'OR location_id IS NOT NULL ' . + 'OR location_ns IS NOT NULL', + $schema->quoteIdentifier($table))); + print "\nFound {$notice->N} notices with location data, inserting"; + while ($notice->fetch()) { + $notloc = Notice_location::getKV('notice_id', $notice->id); + if ($notloc instanceof Notice_location) { + print "-"; + continue; + } + $notloc = new Notice_location(); + $notloc->notice_id = $notice->id; + $notloc->lat= $notice->lat; + $notloc->lon= $notice->lon; + $notloc->location_id= $notice->location_id; + $notloc->location_ns= $notice->location_ns; + $notloc->insert(); + print "."; + } + print "\n"; + } + + /** + * Make sure constraints are met before upgrading, if foreign keys + * are not already in use. + * 2016-03-31 + */ + if (!isset($schemadef['foreign keys'])) { + $newschemadef = self::schemaDef(); + printfnq("\nConstraint checking Notice table...\n"); + /** + * Improve typing and make sure no NULL values in any id-related columns are 0 + * 2016-03-31 + */ + foreach (['reply_to', 'repeat_of'] as $field) { + $notice = new Notice(); // reset the object + $notice->query(sprintf('UPDATE %1$s SET %2$s=NULL WHERE %2$s=0', $notice->escapedTableName(), $field)); + // Now we're sure that no Notice entries have repeat_of=0, only an id > 0 or NULL + unset($notice); + } + + /** + * This Will find foreign keys which do not fulfill the constraints and fix + * where appropriate, such as delete when "repeat_of" ID not found in notice.id + * or set to NULL for "reply_to" in the same case. + * 2016-03-31 + * + * XXX: How does this work if we would use multicolumn foreign keys? + */ + foreach (['reply_to' => 'reset', 'repeat_of' => 'delete', 'profile_id' => 'delete'] as $field=>$action) { + $notice = new Notice(); + + $fkeyname = $notice->tableName().'_'.$field.'_fkey'; + assert(isset($newschemadef['foreign keys'][$fkeyname])); + assert($newschemadef['foreign keys'][$fkeyname]); + + $foreign_key = $newschemadef['foreign keys'][$fkeyname]; + $fkeytable = $foreign_key[0]; + assert(isset($foreign_key[1][$field])); + $fkeycol = $foreign_key[1][$field]; + + printfnq("* {$fkeyname} ({$field} => {$fkeytable}.{$fkeycol})\n"); + + // NOTE: Above we set all repeat_of to NULL if they were 0, so this really gets them all. + $notice->whereAdd(sprintf('%1$s NOT IN (SELECT %2$s FROM %3$s)', $field, $fkeycol, $fkeytable)); + if ($notice->find()) { + printfnq("\tFound {$notice->N} notices with {$field} NOT IN notice.id, {$action}ing..."); + switch ($action) { + case 'delete': // since it's a directly dependant notice for an unknown ID we don't want it in our DB + while ($notice->fetch()) { + $notice->delete(); + } + break; + case 'reset': // just set it to NULL to be compatible with our constraints, if it was related to an unknown ID + $ids = []; + foreach ($notice->fetchAll('id') as $id) { + settype($id, 'int'); + $ids[] = $id; + } + unset($notice); + $notice = new Notice(); + $notice->query(sprintf('UPDATE %1$s SET %2$s=NULL WHERE id IN (%3$s)', + $notice->escapedTableName(), + $field, + implode(',', $ids))); + break; + default: + throw new ServerException('The programmer sucks, invalid action name when fixing table.'); + } + printfnq("DONE.\n"); + } + unset($notice); + } } - // Then we make sure the Notice_location table is created! - $schema->ensureTable('notice_location', Notice_location::schemaDef()); + } - // Then we continue on our road to migration! - echo "\nFound old $table table, moving location data to 'notice_location' table... (this will probably take a LONG time, but can be aborted and continued)"; + public function delPref($namespace, $topic) { + return Notice_prefs::setData($this, $namespace, $topic, null); + } - $notice = new Notice(); - $notice->query(sprintf('SELECT id, lat, lon, location_id, location_ns FROM %1$s ' . - 'WHERE lat IS NOT NULL ' . - 'OR lon IS NOT NULL ' . - 'OR location_id IS NOT NULL ' . - 'OR location_ns IS NOT NULL', - $schema->quoteIdentifier($table))); - print "\nFound {$notice->N} notices with location data, inserting"; - while ($notice->fetch()) { - $notloc = Notice_location::getKV('notice_id', $notice->id); - if ($notloc instanceof Notice_location) { - print "-"; - continue; - } - $notloc = new Notice_location(); - $notloc->notice_id = $notice->id; - $notloc->lat= $notice->lat; - $notloc->lon= $notice->lon; - $notloc->location_id= $notice->location_id; - $notloc->location_ns= $notice->location_ns; - $notloc->insert(); - print "."; + public function getPref($namespace, $topic, $default=null) { + // If you want an exception to be thrown, call Notice_prefs::getData directly + try { + return Notice_prefs::getData($this, $namespace, $topic, $default); + } catch (NoResultException $e) { + return null; } - print "\n"; + } + + // The same as getPref but will fall back to common_config value for the same namespace/topic + public function getConfigPref($namespace, $topic) + { + return Notice_prefs::getConfigData($this, $namespace, $topic); + } + + public function setPref($namespace, $topic, $data) { + return Notice_prefs::setData($this, $namespace, $topic, $data); } + + public function delPref($namespace, $topic) { + return Notice_prefs::setData($this, $namespace, $topic, null); + } + + public function getPref($namespace, $topic, $default=null) { + // If you want an exception to be thrown, call Notice_prefs::getData directly + try { + return Notice_prefs::getData($this, $namespace, $topic, $default); + } catch (NoResultException $e) { + return null; + } + } + + // The same as getPref but will fall back to common_config value for the same namespace/topic + public function getConfigPref($namespace, $topic) + { + return Notice_prefs::getConfigData($this, $namespace, $topic); + } + + public function setPref($namespace, $topic, $data) { + return Notice_prefs::setData($this, $namespace, $topic, $data); + } }