| 
									
										
										
										
											2013-01-24 17:23:05 -08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @group conpherence | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | abstract class ConpherenceController extends PhabricatorController { | 
					
						
							|  |  |  |   private $conpherences; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Try for a full set of unread conpherences, and if we fail | 
					
						
							|  |  |  |    * load read conpherences. Additional conpherences in either category | 
					
						
							|  |  |  |    * are loaded asynchronously. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   public function loadStartingConpherences($current_selection_epoch = null) { | 
					
						
							|  |  |  |     $user = $this->getRequest()->getUser(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $read_participant_query = id(new ConpherenceParticipantQuery()) | 
					
						
							|  |  |  |       ->withParticipantPHIDs(array($user->getPHID())); | 
					
						
							|  |  |  |     $read_status =  ConpherenceParticipationStatus::UP_TO_DATE; | 
					
						
							|  |  |  |     if ($current_selection_epoch) { | 
					
						
							|  |  |  |       $read_one = $read_participant_query | 
					
						
							|  |  |  |         ->withParticipationStatus($read_status) | 
					
						
							|  |  |  |         ->withDateTouched($current_selection_epoch, '>') | 
					
						
							|  |  |  |         ->execute(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       $read_two = $read_participant_query | 
					
						
							|  |  |  |         ->withDateTouched($current_selection_epoch, '<=') | 
					
						
							|  |  |  |         ->execute(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       $read = array_merge($read_one, $read_two); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       $read = $read_participant_query | 
					
						
							|  |  |  |         ->withParticipationStatus($read_status) | 
					
						
							|  |  |  |         ->execute(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $unread_status = ConpherenceParticipationStatus::BEHIND; | 
					
						
							| 
									
										
										
										
											2013-01-26 17:14:58 -08:00
										 |  |  |     $unread = id(new ConpherenceParticipantQuery()) | 
					
						
							|  |  |  |       ->withParticipantPHIDs(array($user->getPHID())) | 
					
						
							| 
									
										
										
										
											2013-01-24 17:23:05 -08:00
										 |  |  |       ->withParticipationStatus($unread_status) | 
					
						
							|  |  |  |       ->execute(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $all_participation = $unread + $read; | 
					
						
							|  |  |  |     $all_conpherence_phids = array_keys($all_participation); | 
					
						
							| 
									
										
										
										
											2013-04-15 16:27:41 -07:00
										 |  |  |     $all_conpherences = array(); | 
					
						
							|  |  |  |     if ($all_conpherence_phids) { | 
					
						
							|  |  |  |       $all_conpherences = id(new ConpherenceThreadQuery()) | 
					
						
							|  |  |  |         ->setViewer($user) | 
					
						
							|  |  |  |         ->withPHIDs($all_conpherence_phids) | 
					
						
							|  |  |  |         ->needParticipantCache(true) | 
					
						
							|  |  |  |         ->execute(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-01-24 17:23:05 -08:00
										 |  |  |     $unread_conpherences = array_select_keys( | 
					
						
							|  |  |  |       $all_conpherences, | 
					
						
							| 
									
										
										
										
											2013-02-19 13:33:10 -08:00
										 |  |  |       array_keys($unread)); | 
					
						
							| 
									
										
										
										
											2013-01-24 17:23:05 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     $read_conpherences = array_select_keys( | 
					
						
							|  |  |  |       $all_conpherences, | 
					
						
							| 
									
										
										
										
											2013-02-19 13:33:10 -08:00
										 |  |  |       array_keys($read)); | 
					
						
							| 
									
										
										
										
											2013-01-24 17:23:05 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-01 12:50:39 -07:00
										 |  |  |     return array($unread_conpherences, $read_conpherences); | 
					
						
							| 
									
										
										
										
											2013-01-24 17:23:05 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-01 12:50:39 -07:00
										 |  |  |   public function buildApplicationMenu() { | 
					
						
							|  |  |  |     $nav = new PhabricatorMenuView(); | 
					
						
							| 
									
										
											  
											
												Fix every HTML issue I could find
Summary:
I attempted to test every interface. I probably missed some stuff, but I at least have some level of confidence that the `phutil_tag` branch is fairly stable.
Fixed these issues:
[1] Fixed a Herald issue with object links in transcripts. Some actions return
links; this was previously hard-coded.
[2] DarkConsole refactoring created an issue where the "`" event handler registered too many times.
[3] Fixed a bug where `strlen($value)` was being checked, but fields may now return array(). Possibly we should implement phutil_is_empty_html() or similar.
[4] Fixed a undefined variable issue for image edit transactions.
[5] Fixed an issue with rendering participant transactions. This required phutil_safe_html() because `pht()` can't handle `array()` for `%s`.
[6] Fixed an issue where feed was entirely overescaped by reverting an overly ambitious render_tag -> tag.
[7] Fixed an issue with strict tables and inserting `''` instead of `0` into an integer column.
[8] Fixed an issue where • was shown escaped.
[9] Fixed an issue where "no data" was overescaped.
[10] Fixed an issue with strict tables and inserting `''` instead of `0` into an integer column.
[11] Fixed an issue with strict tables and inserting `''`.
[12] Fixed an issue with missing space after ":" for mini panels.
Encountered (but did not fix) these issues:
[X1] "e" works incorrectly on comments you are not allowed to edit. Did not fix.
[X2] Coverage currently interacts incorrectly with "--everything" for Phutil tests.
Test Plan:
  - Viewed Differential.
  - Created a diff via copy/paste.
  - Viewed standalone diff.
  - Jumped to diff via changeset table.
  - Created a revision.
  - Updated revision.
  - Added a comment.
  - Edited revision dependencies.
  - Edited revision tasks.
  - Viewed MetaMTA transcripts.
  - Viewed Herald transcripts [1].
  - Downloaded raw diff.
  - Flagged / unflagged revision.
  - Added/edited/deleted inline comment.
  - Collapsed/expanded file.
  - Did show raw left.
  - Did show raw right.
  - Checked previews for available actions.
  - Clicked remarkup buttons
  - Used filetree view.
  - Used keyboard: F, j, k, J, K, n, p, t, h, "?" [2] [X1].
  - Created a meme.
  - Uploaded a file via drag and drop.
  - Viewed a revision with no reviewers.
  - Viewed a revision with >100 files.
  - Viewed various other revisions [3].
  - Viewed an image diff.
  - Added image diff inline comments.
  - Viewed Maniphest.
  - Ran various queries.
  - Created task.
  - Created similar task.
  - Added comments to tasks.
  - Ran custom query.
  - Saved custom query.
  - Edited custom queries.
  - Drag-reordered tasks.
  - Batch edited tasks.
  - Exported tasks to excel.
  - Looked at reports (issue in T2311 notwithstanding).
  - Viewed Diffusion.
  - Browsed Git, SVN, HG repositories.
  - Looked at history, browse, change, commit views.
  - Viewed audit.
  - Performed various audit searches.
  - Viewed Paste.
  - Performed paste searches.
  - Created, edited, forked paste.
  - Viewed Phriction.
  - Edited a page.
  - Viewed edit history.
  - Used search typeahead to search for user / application.
  - Used search to search for text.
  - Viewed Phame.
  - Viewed Blog, Post.
  - Viewed live post.
  - Published/unpublished post.
  - Previewed post.
  - Viewed Pholio.
  - Edited/commented mock.
  - Viewed ponder.
  - Viewed question.
  - Added answer/comment.
  - Viewed Diviner.
  - Viewed Conpherence [4] [5].
  - Made Conpherence updates.
  - Viewed calendar.
  - Created status.
  - Viewed status.
  - Viewed Feed [6].
  - Viewed Projects.
  - Viewed project detail.
  - Edited project.
  - Viewed Owners.
  - Viewed package detail.
  - Edited package [7].
  - Viewed flags.
  - Edited flag.
  - Deleted flag.
  - Viewed Herald.
  - Viewed rules.
  - Created rule.
  - Edited rule.
  - Viewed edit log.
  - Viewed transcripts.
  - Inspected a transcript.
  - Viewed People.
  - Viewed list.
  - Administrated user.
  - Checked username/delete stuff.
  - Looked at create/import LDAP/activity logs.
  - Looked at a user profile.
  - Looked at user about page.
  - Looked at Repositories.
  - Edited repository.
  - Edited arcanist project.
  - Looked at daemons.
  - Looked at all daemons [8].
  - Viewed combined log.
  - Looked at configuration.
  - Edited configuration.
  - Looked at setup issues [9].
  - Looked at current settings.
  - Looked at application list.
  - Installed / uninstalled applications [10].
  - Looked at mailing lists.
  - Created a mailing list.
  - Edited a mailing list.
  - Looked at sent mail.
  - Looked at received mail.
  - Looked at send/receive tests.
  - Looked at settings.
  - Clicked through all the panels.
  - Looked at slowvote.
  - Created a slowvote [11].
  - Voted in a slowvote.
  - Looked at Macro.
  - Created a macro.
  - Edited a macro.
  - Commented on a macro.
  - Looked at Countdown.
  - Created a Countdown.
  - Looked at it.
  - Looked at Drydock.
  - Poked around a bit.
  - Looked at Fact.
  - Poked around a bit.
  - Looked at files.
  - Looked at a file.
  - Uploaded a file.
  - Looked at Conduit.
  - Made a Conduit call.
  - Looked at UIExamples.
  - Looked at PHPAST.
  - Looked at PHIDs.
  - Looked at notification menu.
  - Looked at notification detail.
  - Logged out.
  - Logged in.
  - Looked at homepage [12].
  - Ran `arc unit --everything --no-coverage` [X2].
Reviewers: vrana, btrahan
Reviewed By: vrana
CC: aran
Maniphest Tasks: T2432
Differential Revision: https://secure.phabricator.com/D4807
											
										 
											2013-02-04 17:06:34 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-01 12:50:39 -07:00
										 |  |  |     $nav->newLink( | 
					
						
							| 
									
										
										
										
											2013-04-15 16:27:41 -07:00
										 |  |  |       pht('New Message'), | 
					
						
							| 
									
										
										
										
											2013-04-01 12:50:39 -07:00
										 |  |  |       $this->getApplicationURI('new/')); | 
					
						
							| 
									
										
										
										
											2013-01-24 17:23:05 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return $nav; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   public function buildApplicationCrumbs() { | 
					
						
							|  |  |  |     $crumbs = parent::buildApplicationCrumbs(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $crumbs | 
					
						
							|  |  |  |       ->addAction( | 
					
						
							|  |  |  |         id(new PhabricatorMenuItemView()) | 
					
						
							| 
									
										
										
										
											2013-04-15 16:27:41 -07:00
										 |  |  |           ->setName(pht('New Message')) | 
					
						
							| 
									
										
										
										
											2013-01-24 17:23:05 -08:00
										 |  |  |           ->setHref($this->getApplicationURI('new/')) | 
					
						
							| 
									
										
										
										
											2013-02-19 13:33:10 -08:00
										 |  |  |           ->setIcon('create')) | 
					
						
							| 
									
										
										
										
											2013-01-24 17:23:05 -08:00
										 |  |  |       ->addCrumb( | 
					
						
							|  |  |  |         id(new PhabricatorCrumbView()) | 
					
						
							| 
									
										
										
										
											2013-02-19 13:33:10 -08:00
										 |  |  |           ->setName(pht('Conpherence'))); | 
					
						
							| 
									
										
										
										
											2013-01-24 17:23:05 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return $crumbs; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-05 15:45:36 -08:00
										 |  |  |   protected function buildHeaderPaneContent(ConpherenceThread $conpherence) { | 
					
						
							|  |  |  |     $user = $this->getRequest()->getUser(); | 
					
						
							|  |  |  |     $display_data = $conpherence->getDisplayData( | 
					
						
							|  |  |  |       $user, | 
					
						
							|  |  |  |       ConpherenceImageData::SIZE_HEAD); | 
					
						
							|  |  |  |     $edit_href = $this->getApplicationURI('update/'.$conpherence->getID().'/'); | 
					
						
							|  |  |  |     $class_mod = $display_data['image_class']; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-01 12:52:30 -07:00
										 |  |  |     return array( | 
					
						
							|  |  |  |       phutil_tag( | 
					
						
							|  |  |  |         'div', | 
					
						
							|  |  |  |         array( | 
					
						
							|  |  |  |           'class' => 'upload-photo' | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         pht('Drop photo here to change this Conpherence photo.')), | 
					
						
							|  |  |  |       javelin_tag( | 
					
						
							|  |  |  |         'a', | 
					
						
							|  |  |  |         array( | 
					
						
							|  |  |  |           'class' => 'edit', | 
					
						
							|  |  |  |           'href' => $edit_href, | 
					
						
							|  |  |  |           'sigil' => 'conpherence-edit-metadata', | 
					
						
							|  |  |  |           'meta' => array( | 
					
						
							|  |  |  |             'action' => 'metadata' | 
					
						
							|  |  |  |           ) | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         ''), | 
					
						
							|  |  |  |       phutil_tag( | 
					
						
							|  |  |  |         'div', | 
					
						
							|  |  |  |         array( | 
					
						
							|  |  |  |           'class' => $class_mod.'header-image', | 
					
						
							|  |  |  |           'style' => 'background-image: url('.$display_data['image'].');' | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         ''), | 
					
						
							|  |  |  |       phutil_tag( | 
					
						
							|  |  |  |         'div', | 
					
						
							|  |  |  |         array( | 
					
						
							|  |  |  |           'class' => $class_mod.'title', | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         $display_data['title']), | 
					
						
							|  |  |  |       phutil_tag( | 
					
						
							|  |  |  |         'div', | 
					
						
							|  |  |  |         array( | 
					
						
							|  |  |  |           'class' => $class_mod.'subtitle', | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         $display_data['subtitle']), | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2013-03-05 15:45:36 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   protected function renderConpherenceTransactions( | 
					
						
							|  |  |  |     ConpherenceThread $conpherence) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $user = $this->getRequest()->getUser(); | 
					
						
							|  |  |  |     $transactions = $conpherence->getTransactions(); | 
					
						
							| 
									
										
										
										
											2013-04-18 16:54:06 -07:00
										 |  |  |     $oldest_transaction_id = 0; | 
					
						
							|  |  |  |     $too_many = ConpherenceThreadQuery::TRANSACTION_LIMIT + 1; | 
					
						
							|  |  |  |     if (count($transactions) == $too_many) { | 
					
						
							|  |  |  |       $last_transaction = end($transactions); | 
					
						
							|  |  |  |       unset($transactions[$last_transaction->getID()]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     $transactions = array_reverse($transactions); | 
					
						
							|  |  |  |     $oldest_transaction = reset($transactions); | 
					
						
							|  |  |  |     $oldest_transaction_id = $oldest_transaction->getID(); | 
					
						
							| 
									
										
										
										
											2013-03-05 15:45:36 -08:00
										 |  |  |     $handles = $conpherence->getHandles(); | 
					
						
							|  |  |  |     $rendered_transactions = array(); | 
					
						
							|  |  |  |     $engine = id(new PhabricatorMarkupEngine()) | 
					
						
							|  |  |  |       ->setViewer($user); | 
					
						
							|  |  |  |     foreach ($transactions as $key => $transaction) { | 
					
						
							|  |  |  |       if ($transaction->shouldHide()) { | 
					
						
							|  |  |  |         unset($transactions[$key]); | 
					
						
							|  |  |  |         continue; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if ($transaction->getComment()) { | 
					
						
							|  |  |  |         $engine->addObject( | 
					
						
							|  |  |  |           $transaction->getComment(), | 
					
						
							|  |  |  |           PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     $engine->process(); | 
					
						
							|  |  |  |     foreach ($transactions as $transaction) { | 
					
						
							|  |  |  |       $rendered_transactions[] = id(new ConpherenceTransactionView()) | 
					
						
							|  |  |  |         ->setUser($user) | 
					
						
							|  |  |  |         ->setConpherenceTransaction($transaction) | 
					
						
							|  |  |  |         ->setHandles($handles) | 
					
						
							|  |  |  |         ->setMarkupEngine($engine) | 
					
						
							|  |  |  |         ->render(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     $latest_transaction_id = $transaction->getID(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return array( | 
					
						
							|  |  |  |       'transactions' => $rendered_transactions, | 
					
						
							| 
									
										
										
										
											2013-04-18 16:54:06 -07:00
										 |  |  |       'latest_transaction_id' => $latest_transaction_id, | 
					
						
							|  |  |  |       'oldest_transaction_id' => $oldest_transaction_id | 
					
						
							| 
									
										
										
										
											2013-03-05 15:45:36 -08:00
										 |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-01-24 17:23:05 -08:00
										 |  |  | } |