editpeopletag.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. <?php
  2. // This file is part of GNU social - https://www.gnu.org/software/social
  3. //
  4. // GNU social is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Affero General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // GNU social is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Affero General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Affero General Public License
  15. // along with GNU social. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * Edit an existing group
  18. *
  19. * @category Group
  20. * @package GNUsocial
  21. * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
  22. */
  23. defined('GNUSOCIAL') || die();
  24. /**
  25. * Add a new group
  26. *
  27. * This is the form for adding a new group
  28. *
  29. * @category Group
  30. * @package GNUsocial
  31. * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
  32. */
  33. class EditpeopletagAction extends Action
  34. {
  35. public $msg;
  36. public $confirm;
  37. public $confirm_args = [];
  38. public function title()
  39. {
  40. if ($_SERVER['REQUEST_METHOD'] == 'POST' && $this->boolean('delete')) {
  41. // TRANS: Title for edit list page after deleting a tag.
  42. // TRANS: %s is a list.
  43. return sprintf(_('Delete %s list'), $this->peopletag->tag);
  44. }
  45. // TRANS: Title for edit list page.
  46. // TRANS: %s is a list.
  47. return sprintf(_('Edit list %s'), $this->peopletag->tag);
  48. }
  49. /**
  50. * Prepare to run
  51. */
  52. public function prepare(array $args = [])
  53. {
  54. parent::prepare($args);
  55. if (!common_logged_in()) {
  56. // TRANS: Error message displayed when trying to perform an action that requires a logged in user.
  57. $this->clientError(_('Not logged in.'));
  58. }
  59. $id = $this->arg('id');
  60. if (common_config('singleuser', 'enabled')) {
  61. $tagger_arg = User::singleUserNickname();
  62. } else {
  63. $tagger_arg = $this->arg('tagger');
  64. }
  65. $tag_arg = $this->arg('tag');
  66. $tagger = common_canonical_nickname($tagger_arg);
  67. $tag = common_canonical_tag($tag_arg);
  68. $current = common_current_user();
  69. // Permanent redirect on non-canonical tag
  70. if ($tagger_arg != $tagger || $tag_arg != $tag) {
  71. $args = array('tagger' => $tagger, 'tag' => $tag);
  72. common_redirect(common_local_url('editpeopletag', $args), 301);
  73. }
  74. $user = null;
  75. if ($id) {
  76. $this->peopletag = Profile_list::getKV('id', $id);
  77. if (!empty($this->peopletag)) {
  78. $user = User::getKV('id', $this->peopletag->tagger);
  79. }
  80. } else {
  81. if (!$tagger) {
  82. // TRANS: Error message displayed when trying to perform an action that requires a tagging user or ID.
  83. $this->clientError(_('No tagger or ID.'), 404);
  84. }
  85. $user = User::getKV('nickname', $tagger);
  86. $this->peopletag = Profile_list::pkeyGet(array('tagger' => $user->id, 'tag' => $tag));
  87. }
  88. if (!$this->peopletag) {
  89. // TRANS: Client error displayed when referring to a non-existing list.
  90. $this->clientError(_('No such list.'), 404);
  91. }
  92. if (!$user) {
  93. // This should not be happening
  94. // TRANS: Client error displayed when referring to non-local user.
  95. $this->clientError(_('Not a local user.'), 404);
  96. }
  97. if ($current->id != $user->id) {
  98. // TRANS: Client error displayed when reting to edit a tag that was not self-created.
  99. $this->clientError(_('You must be the creator of the tag to edit it.'), 404);
  100. }
  101. $this->tagger = $user->getProfile();
  102. return true;
  103. }
  104. /**
  105. * Handle the request
  106. *
  107. * On GET, show the form. On POST, try to save the group.
  108. *
  109. * @param array $args unused
  110. *
  111. * @return void
  112. */
  113. public function handle()
  114. {
  115. parent::handle();
  116. if ($_SERVER['REQUEST_METHOD'] == 'POST') {
  117. $this->trySave();
  118. } else {
  119. $this->showForm();
  120. }
  121. }
  122. public function showConfirm($msg = null, $fwd = null)
  123. {
  124. $this->confirm = $msg;
  125. $this->confirm_args = $fwd;
  126. $this->showPage();
  127. }
  128. public function showConfirmForm()
  129. {
  130. $this->elementStart(
  131. 'form',
  132. [
  133. 'id' => 'form_peopletag_edit_confirm',
  134. 'class' => 'form_settings',
  135. 'method' => 'post',
  136. 'action' => common_local_url(
  137. 'editpeopletag',
  138. [
  139. 'tagger' => $this->tagger->nickname,
  140. 'tag' => $this->peopletag->tag,
  141. ]
  142. ),
  143. ]
  144. );
  145. $this->elementStart('fieldset');
  146. $this->hidden('token', common_session_token());
  147. $this->hidden('id', $this->arg('id'));
  148. foreach ($this->confirm_args as $key => $val) {
  149. $this->hidden($key, $val);
  150. }
  151. $this->submit(
  152. 'form_action-no',
  153. _m('BUTTON', 'No'),
  154. 'submit form_action-primary',
  155. 'cancel'
  156. );
  157. $this->submit(
  158. 'form_action-yes',
  159. _m('BUTTON', 'Yes'),
  160. 'submit form_action-secondary',
  161. 'confirm'
  162. );
  163. $this->elementEnd('fieldset');
  164. $this->elementEnd('form');
  165. }
  166. public function showForm($msg = null)
  167. {
  168. $this->msg = $msg;
  169. $this->showPage();
  170. }
  171. public function showObjectNav()
  172. {
  173. $nav = new PeopletagGroupNav($this, $this->peopletag);
  174. $nav->show();
  175. }
  176. public function showContent()
  177. {
  178. if ($this->confirm) {
  179. $this->showConfirmForm();
  180. return;
  181. }
  182. $form = new PeopletagEditForm($this, $this->peopletag);
  183. $form->show();
  184. $form->showProfileList();
  185. }
  186. public function showPageNotice()
  187. {
  188. if ($this->msg) {
  189. $this->element('p', 'error', $this->msg);
  190. } elseif ($this->confirm) {
  191. $this->element('p', 'instructions', $this->confirm);
  192. } else {
  193. $this->element(
  194. 'p',
  195. 'instructions',
  196. // TRANS: Form instruction for edit list form.
  197. _('Use this form to edit the list.')
  198. );
  199. }
  200. }
  201. public function showScripts()
  202. {
  203. parent::showScripts();
  204. $this->autofocus('tag');
  205. }
  206. public function trySave()
  207. {
  208. $tag = common_canonical_tag($this->trimmed('tag'));
  209. $description = $this->trimmed('description');
  210. $private = $this->boolean('private');
  211. $delete = $this->arg('delete');
  212. $confirm = $this->arg('confirm');
  213. $cancel = $this->arg('cancel');
  214. if ($delete && $cancel) {
  215. // TRANS: Form validation error displayed if the form data for deleting a tag was incorrect.
  216. $this->showForm(_('Delete aborted.'));
  217. return;
  218. }
  219. $set_private = $private && $this->peopletag->private != $private;
  220. if ($delete && !$confirm) {
  221. // TRANS: Text in confirmation dialog for deleting a tag.
  222. $this->showConfirm(_('Deleting this tag will permanantly remove ' .
  223. 'all its subscription and membership records. ' .
  224. 'Do you still want to continue?'), array('delete' => 1));
  225. return;
  226. } elseif (common_valid_tag($tag)) {
  227. // TRANS: Form validation error displayed if a given tag is invalid.
  228. $this->showForm(_('Invalid tag.'));
  229. return;
  230. } elseif ($tag != $this->peopletag->tag && $this->tagExists($tag)) {
  231. // TRANS: Form validation error displayed if a given tag is already present.
  232. // TRANS: %s is the already present tag.
  233. $this->showForm(sprintf(_('You already have a tag named %s.'), $tag));
  234. return;
  235. } elseif (Profile_list::descriptionTooLong($description)) {
  236. $this->showForm(sprintf(
  237. // TRANS: Client error shown when providing too long a description when editing a list.
  238. // TRANS: %d is the maximum number of allowed characters.
  239. _m('Description is too long (maximum %d character).',
  240. 'Description is too long (maximum %d characters).',
  241. Profile_list::maxDescription()),
  242. Profile_list::maxDescription()
  243. ));
  244. return;
  245. } elseif ($set_private && !$confirm && !$cancel) {
  246. $fwd = array('tag' => $tag,
  247. 'description' => $description,
  248. 'private' => (int) $private);
  249. // TRANS: Text in confirmation dialog for setting a tag from public to private.
  250. $this->showConfirm(_('Setting a public tag as private will ' .
  251. 'permanently remove all the existing ' .
  252. 'subscriptions to it. Do you still want to continue?'), $fwd);
  253. return;
  254. }
  255. // We tested $delete && !$confirm earlier so confirmation is required before getting here
  256. if ($delete) {
  257. // This might take quite a bit of time.
  258. $this->peopletag->delete();
  259. // send home.
  260. common_redirect(common_local_url('all', array('nickname' => $this->tagger->getNickname())), 303);
  261. }
  262. $this->peopletag->query('START TRANSACTION');
  263. $orig = clone($this->peopletag);
  264. $this->peopletag->tag = $tag;
  265. $this->peopletag->description = $description;
  266. if (!$set_private || $confirm) {
  267. $this->peopletag->private = $private;
  268. }
  269. $result = $this->peopletag->update($orig);
  270. if (!$result) {
  271. common_log_db_error($this->group, 'UPDATE', __FILE__);
  272. // TRANS: Server error displayed when updating a list fails.
  273. $this->serverError(_('Could not update list.'));
  274. }
  275. $this->peopletag->query('COMMIT');
  276. if ($set_private && $confirm) {
  277. Profile_tag_subscription::cleanup($this->peopletag);
  278. }
  279. if ($tag != $orig->tag) {
  280. common_redirect(
  281. common_local_url(
  282. 'editpeopletag',
  283. [
  284. 'tagger' => $this->tagger->nickname,
  285. 'tag' => $tag,
  286. ]
  287. ),
  288. 303
  289. );
  290. } else {
  291. // TRANS: Edit list form success message.
  292. $this->showForm(_('Options saved.'));
  293. }
  294. }
  295. public function tagExists($tag)
  296. {
  297. $args = array('tagger' => $this->tagger->id, 'tag' => $tag);
  298. $ptag = Profile_list::pkeyGet($args);
  299. return !empty($ptag);
  300. }
  301. }