Friendica Communications Platform (please note that this is a clone of the repository at github, issues are handled there) https://friendi.ca
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

update.php 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. <?php
  2. use Friendica\Core\Addon;
  3. use Friendica\Core\Config;
  4. use Friendica\Core\L10n;
  5. use Friendica\Core\Logger;
  6. use Friendica\Core\PConfig;
  7. use Friendica\Core\Update;
  8. use Friendica\Core\Worker;
  9. use Friendica\Database\DBA;
  10. use Friendica\Model\Contact;
  11. use Friendica\Model\GContact;
  12. use Friendica\Model\Item;
  13. use Friendica\Model\User;
  14. use Friendica\Util\DateTimeFormat;
  15. use Friendica\Worker\Delivery;
  16. /**
  17. *
  18. * update.php - automatic system update
  19. *
  20. * This function is responsible for doing post update changes to the data
  21. * (not the structure) in the database.
  22. *
  23. * Database structure changes are done in static/dbstructure.config.php
  24. *
  25. * If there is a need for a post process to a structure change, update this file
  26. * by adding a new function at the end with the number of the new DB_UPDATE_VERSION.
  27. *
  28. * The numbered script in this file has to be exactly like the DB_UPDATE_VERSION
  29. *
  30. * Example:
  31. * You are currently on version 4711 and you are preparing changes that demand an update script.
  32. *
  33. * 1. Create a function "update_4712()" here in the update.php
  34. * 2. Apply the needed structural changes in static/dbStructure.php
  35. * 3. Set DB_UPDATE_VERSION in static/dbstructure.config.php to 4712.
  36. *
  37. * If you need to run a script before the database update, name the function "pre_update_4712()"
  38. */
  39. function update_1178()
  40. {
  41. require_once 'mod/profiles.php';
  42. $profiles = q("SELECT `uid`, `about`, `locality`, `pub_keywords`, `gender` FROM `profile` WHERE `is-default`");
  43. foreach ($profiles as $profile) {
  44. if ($profile["about"].$profile["locality"].$profile["pub_keywords"].$profile["gender"] == "") {
  45. continue;
  46. }
  47. $profile["pub_keywords"] = profile_clean_keywords($profile["pub_keywords"]);
  48. $r = q("UPDATE `contact` SET `about` = '%s', `location` = '%s', `keywords` = '%s', `gender` = '%s' WHERE `self` AND `uid` = %d",
  49. DBA::escape($profile["about"]),
  50. DBA::escape($profile["locality"]),
  51. DBA::escape($profile["pub_keywords"]),
  52. DBA::escape($profile["gender"]),
  53. intval($profile["uid"])
  54. );
  55. }
  56. }
  57. function update_1179()
  58. {
  59. if (Config::get('system', 'no_community_page')) {
  60. Config::set('system', 'community_page_style', CP_NO_COMMUNITY_PAGE);
  61. }
  62. // Update the central item storage with uid=0
  63. Worker::add(PRIORITY_LOW, "threadupdate");
  64. return Update::SUCCESS;
  65. }
  66. function update_1181()
  67. {
  68. // Fill the new fields in the term table.
  69. Worker::add(PRIORITY_LOW, "TagUpdate");
  70. return Update::SUCCESS;
  71. }
  72. function update_1189()
  73. {
  74. if (strlen(Config::get('system', 'directory_submit_url')) &&
  75. !strlen(Config::get('system', 'directory'))) {
  76. Config::set('system', 'directory', dirname(Config::get('system', 'directory_submit_url')));
  77. Config::delete('system', 'directory_submit_url');
  78. }
  79. return Update::SUCCESS;
  80. }
  81. function update_1191()
  82. {
  83. Config::set('system', 'maintenance', 1);
  84. if (Addon::isEnabled('forumlist')) {
  85. $addon = 'forumlist';
  86. $addons = Config::get('system', 'addon');
  87. $addons_arr = [];
  88. if ($addons) {
  89. $addons_arr = explode(",", str_replace(" ", "", $addons));
  90. $idx = array_search($addon, $addons_arr);
  91. if ($idx !== false) {
  92. unset($addons_arr[$idx]);
  93. //delete forumlist manually from addon and hook table
  94. // since Addon::uninstall() don't work here
  95. q("DELETE FROM `addon` WHERE `name` = 'forumlist' ");
  96. q("DELETE FROM `hook` WHERE `file` = 'addon/forumlist/forumlist.php' ");
  97. Config::set('system', 'addon', implode(", ", $addons_arr));
  98. }
  99. }
  100. }
  101. // select old formlist addon entries
  102. $r = q("SELECT `uid`, `cat`, `k`, `v` FROM `pconfig` WHERE `cat` = '%s' ",
  103. DBA::escape('forumlist')
  104. );
  105. // convert old forumlist addon entries in new config entries
  106. if (DBA::isResult($r)) {
  107. foreach ($r as $rr) {
  108. $uid = $rr['uid'];
  109. $family = $rr['cat'];
  110. $key = $rr['k'];
  111. $value = $rr['v'];
  112. if ($key === 'randomise') {
  113. PConfig::delete($uid, $family, $key);
  114. }
  115. if ($key === 'show_on_profile') {
  116. if ($value) {
  117. PConfig::set($uid, feature, forumlist_profile, $value);
  118. }
  119. PConfig::delete($uid, $family, $key);
  120. }
  121. if ($key === 'show_on_network') {
  122. if ($value) {
  123. PConfig::set($uid, feature, forumlist_widget, $value);
  124. }
  125. PConfig::delete($uid, $family, $key);
  126. }
  127. }
  128. }
  129. Config::set('system', 'maintenance', 0);
  130. return Update::SUCCESS;
  131. }
  132. function update_1203()
  133. {
  134. $r = q("UPDATE `user` SET `account-type` = %d WHERE `page-flags` IN (%d, %d)",
  135. DBA::escape(User::ACCOUNT_TYPE_COMMUNITY),
  136. DBA::escape(User::PAGE_FLAGS_COMMUNITY),
  137. DBA::escape(User::PAGE_FLAGS_PRVGROUP)
  138. );
  139. }
  140. function update_1244()
  141. {
  142. // Sets legacy_password for all legacy hashes
  143. DBA::update('user', ['legacy_password' => true], ['SUBSTR(password, 1, 4) != "$2y$"']);
  144. // All legacy hashes are re-hashed using the new secure hashing function
  145. $stmt = DBA::select('user', ['uid', 'password'], ['legacy_password' => true]);
  146. while ($user = DBA::fetch($stmt)) {
  147. DBA::update('user', ['password' => User::hashPassword($user['password'])], ['uid' => $user['uid']]);
  148. }
  149. // Logged in users are forcibly logged out
  150. DBA::delete('session', ['1 = 1']);
  151. return Update::SUCCESS;
  152. }
  153. function update_1245()
  154. {
  155. $rino = Config::get('system', 'rino_encrypt');
  156. if (!$rino) {
  157. return Update::SUCCESS;
  158. }
  159. Config::set('system', 'rino_encrypt', 1);
  160. return Update::SUCCESS;
  161. }
  162. function update_1247()
  163. {
  164. // Removing hooks with the old name
  165. DBA::e("DELETE FROM `hook`
  166. WHERE `hook` LIKE 'plugin_%'");
  167. // Make sure we install the new renamed ones
  168. Addon::reload();
  169. }
  170. function update_1260()
  171. {
  172. Config::set('system', 'maintenance', 1);
  173. Config::set(
  174. 'system',
  175. 'maintenance_reason',
  176. L10n::t(
  177. '%s: Updating author-id and owner-id in item and thread table. ',
  178. DateTimeFormat::utcNow().' '.date('e')
  179. )
  180. );
  181. $items = DBA::p("SELECT `id`, `owner-link`, `owner-name`, `owner-avatar`, `network` FROM `item`
  182. WHERE `owner-id` = 0 AND `owner-link` != ''");
  183. while ($item = DBA::fetch($items)) {
  184. $contact = ['url' => $item['owner-link'], 'name' => $item['owner-name'],
  185. 'photo' => $item['owner-avatar'], 'network' => $item['network']];
  186. $cid = Contact::getIdForURL($item['owner-link'], 0, false, $contact);
  187. if (empty($cid)) {
  188. continue;
  189. }
  190. Item::update(['owner-id' => $cid], ['id' => $item['id']]);
  191. }
  192. DBA::close($items);
  193. DBA::e("UPDATE `thread` INNER JOIN `item` ON `thread`.`iid` = `item`.`id`
  194. SET `thread`.`owner-id` = `item`.`owner-id` WHERE `thread`.`owner-id` = 0");
  195. $items = DBA::p("SELECT `id`, `author-link`, `author-name`, `author-avatar`, `network` FROM `item`
  196. WHERE `author-id` = 0 AND `author-link` != ''");
  197. while ($item = DBA::fetch($items)) {
  198. $contact = ['url' => $item['author-link'], 'name' => $item['author-name'],
  199. 'photo' => $item['author-avatar'], 'network' => $item['network']];
  200. $cid = Contact::getIdForURL($item['author-link'], 0, false, $contact);
  201. if (empty($cid)) {
  202. continue;
  203. }
  204. Item::update(['author-id' => $cid], ['id' => $item['id']]);
  205. }
  206. DBA::close($items);
  207. DBA::e("UPDATE `thread` INNER JOIN `item` ON `thread`.`iid` = `item`.`id`
  208. SET `thread`.`author-id` = `item`.`author-id` WHERE `thread`.`author-id` = 0");
  209. Config::set('system', 'maintenance', 0);
  210. return Update::SUCCESS;
  211. }
  212. function update_1261()
  213. {
  214. // This fixes the results of an issue in the develop branch of 2018-05.
  215. DBA::update('contact', ['blocked' => false, 'pending' => false], ['uid' => 0, 'blocked' => true, 'pending' => true]);
  216. return Update::SUCCESS;
  217. }
  218. function update_1278()
  219. {
  220. Config::set('system', 'maintenance', 1);
  221. Config::set(
  222. 'system',
  223. 'maintenance_reason',
  224. L10n::t(
  225. '%s: Updating post-type.',
  226. DateTimeFormat::utcNow().' '.date('e')
  227. )
  228. );
  229. Item::update(['post-type' => Item::PT_PAGE], ['bookmark' => true]);
  230. Item::update(['post-type' => Item::PT_PERSONAL_NOTE], ['type' => 'note']);
  231. Config::set('system', 'maintenance', 0);
  232. return Update::SUCCESS;
  233. }
  234. function update_1288()
  235. {
  236. // Updates missing `uri-id` values
  237. DBA::e("UPDATE `item-activity` INNER JOIN `item` ON `item`.`iaid` = `item-activity`.`id` SET `item-activity`.`uri-id` = `item`.`uri-id` WHERE `item-activity`.`uri-id` IS NULL OR `item-activity`.`uri-id` = 0");
  238. DBA::e("UPDATE `item-content` INNER JOIN `item` ON `item`.`icid` = `item-content`.`id` SET `item-content`.`uri-id` = `item`.`uri-id` WHERE `item-content`.`uri-id` IS NULL OR `item-content`.`uri-id` = 0");
  239. return Update::SUCCESS;
  240. }
  241. // Post-update script of PR 5751
  242. function update_1298()
  243. {
  244. $keys = ['gender', 'marital', 'sexual'];
  245. foreach ($keys as $translateKey) {
  246. $allData = DBA::select('profile', ['id', $translateKey]);
  247. $allLangs = L10n::getAvailableLanguages();
  248. $success = 0;
  249. $fail = 0;
  250. foreach ($allData as $key => $data) {
  251. $toTranslate = $data[$translateKey];
  252. if ($toTranslate != '') {
  253. foreach ($allLangs as $key => $lang) {
  254. $a = new \stdClass();
  255. $a->strings = [];
  256. // First we get the the localizations
  257. if (file_exists("view/lang/$lang/strings.php")) {
  258. include "view/lang/$lang/strings.php";
  259. }
  260. if (file_exists("addon/morechoice/lang/$lang/strings.php")) {
  261. include "addon/morechoice/lang/$lang/strings.php";
  262. }
  263. $localizedStrings = $a->strings;
  264. unset($a);
  265. $key = array_search($toTranslate, $localizedStrings);
  266. if ($key !== false) {
  267. break;
  268. }
  269. // defaulting to empty string
  270. $key = '';
  271. }
  272. if ($key == '') {
  273. $fail++;
  274. } else {
  275. DBA::update('profile', [$translateKey => $key], ['id' => $data['id']]);
  276. Logger::notice('Updated contact', ['action' => 'update', 'contact' => $data['id'], "$translateKey" => $key,
  277. 'was' => $data[$translateKey]]);
  278. Worker::add(PRIORITY_LOW, 'ProfileUpdate', $data['id']);
  279. Contact::updateSelfFromUserID($data['id']);
  280. GContact::updateForUser($data['id']);
  281. $success++;
  282. }
  283. }
  284. }
  285. Logger::notice($translateKey . " fix completed", ['action' => 'update', 'translateKey' => $translateKey, 'Success' => $success, 'Fail' => $fail ]);
  286. }
  287. return Update::SUCCESS;
  288. }
  289. function update_1309()
  290. {
  291. $queue = DBA::select('queue', ['id', 'cid', 'guid']);
  292. while ($entry = DBA::fetch($queue)) {
  293. $contact = DBA::selectFirst('contact', ['uid'], ['id' => $entry['cid']]);
  294. if (!DBA::isResult($contact)) {
  295. continue;
  296. }
  297. $item = Item::selectFirst(['id', 'gravity'], ['uid' => $contact['uid'], 'guid' => $entry['guid']]);
  298. if (!DBA::isResult($item)) {
  299. continue;
  300. }
  301. $deliver_options = ['priority' => PRIORITY_MEDIUM, 'dont_fork' => true];
  302. Worker::add($deliver_options, 'Delivery', Delivery::POST, $item['id'], $entry['cid']);
  303. Logger::info('Added delivery worker', ['command' => $cmd, 'item' => $item['id'], 'contact' => $entry['cid']]);
  304. DBA::delete('queue', ['id' => $entry['id']]);
  305. }
  306. return Update::SUCCESS;
  307. }
  308. function update_1315()
  309. {
  310. DBA::delete('item-delivery-data', ['postopts' => '', 'inform' => '', 'queue_count' => 0, 'queue_done' => 0]);
  311. return Update::SUCCESS;
  312. }
  313. function update_1318()
  314. {
  315. DBA::update('profile', ['marital' => "In a relation"], ['marital' => "Unavailable"]);
  316. DBA::update('profile', ['marital' => "Single"], ['marital' => "Available"]);
  317. Worker::add(PRIORITY_LOW, 'ProfileUpdate');
  318. return Update::SUCCESS;
  319. }
  320. function update_1323()
  321. {
  322. $users = DBA::select('user', ['uid']);
  323. while ($user = DBA::fetch($users)) {
  324. Contact::updateSelfFromUserID($user['uid']);
  325. }
  326. DBA::close($users);
  327. return Update::SUCCESS;
  328. }