From 506d6725b6e0c853893cdb42c28c2e1ad5be593c Mon Sep 17 00:00:00 2001 From: Daniel Wehner Date: Sat, 10 Jan 2015 20:02:45 +0100 Subject: [PATCH 1/9] extract logic to ensure logged in user --- src/DrupalPatchUtils/Command/CommandBase.php | 16 ++++++++++++++++ src/DrupalPatchUtils/Command/CreateIssue.php | 4 +--- src/DrupalPatchUtils/Command/PostComment.php | 4 +--- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/DrupalPatchUtils/Command/CommandBase.php b/src/DrupalPatchUtils/Command/CommandBase.php index 0995451..b6876d9 100644 --- a/src/DrupalPatchUtils/Command/CommandBase.php +++ b/src/DrupalPatchUtils/Command/CommandBase.php @@ -10,6 +10,7 @@ namespace DrupalPatchUtils\Command; use DrupalPatchUtils\Config; +use DrupalPatchUtils\DoBrowser; use DrupalPatchUtils\Issue; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Output\OutputInterface; @@ -90,4 +91,19 @@ protected function getDialog() { protected function askConfirmation (OutputInterface $output, $question, $default = FALSE) { return $this->getDialog()->askConfirmation($output, $question, $default); } + + /** + * Ensure that the user is logged in. + * + * @param \DrupalPatchUtils\DoBrowser $browser + * The d.o. browser + * @param \Symfony\Component\Console\Output\OutputInterface $output + * The output. + */ + protected function ensureUserIsLoggedIn(DoBrowser $browser, OutputInterface $output) { + if (!$browser->loggedIn()) { + $browser->login($this->getConfig()->getDrupalUser(), $this->ask($output, "Enter your Drupal.org password: ", '', TRUE)); + } + } + } diff --git a/src/DrupalPatchUtils/Command/CreateIssue.php b/src/DrupalPatchUtils/Command/CreateIssue.php index 0b82e41..edfffca 100644 --- a/src/DrupalPatchUtils/Command/CreateIssue.php +++ b/src/DrupalPatchUtils/Command/CreateIssue.php @@ -44,9 +44,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } $browser = new DoBrowser(); - if (!$browser->loggedIn()) { - $browser->login($this->getConfig()->getDrupalUser(), $this->ask($output, "Enter your Drupal.org password: ", '', TRUE)); - } + $this->ensureUserIsLoggedIn($browser, $output); $project = $input->getArgument('project'); $project_form = $browser->getIssueForm($project); diff --git a/src/DrupalPatchUtils/Command/PostComment.php b/src/DrupalPatchUtils/Command/PostComment.php index 3d0e654..1c385e8 100644 --- a/src/DrupalPatchUtils/Command/PostComment.php +++ b/src/DrupalPatchUtils/Command/PostComment.php @@ -34,9 +34,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $issue = $this->getIssue($input->getArgument('url')); if ($issue) { $browser = new DoBrowser(); - if (!$browser->loggedIn()) { - $browser->login($this->getConfig()->getDrupalUser(), $this->ask($output, "Enter your Drupal.org password: ", '', TRUE)); - } + $this->ensureUserIsLoggedIn($browser, $output); $comment_form = $browser->getCommentForm($issue->getUri()); From cfcc50bd01de56a55327b2e519d81940b269bec1 Mon Sep 17 00:00:00 2001 From: Daniel Wehner Date: Sat, 10 Jan 2015 20:03:09 +0100 Subject: [PATCH 2/9] move generic issue-metadata into DoFormBase --- src/DrupalPatchUtils/DoFormBase.php | 48 ++++++++++++++++++++++++++++- src/DrupalPatchUtils/IssueForm.php | 43 -------------------------- 2 files changed, 47 insertions(+), 44 deletions(-) diff --git a/src/DrupalPatchUtils/DoFormBase.php b/src/DrupalPatchUtils/DoFormBase.php index ae2a515..1182ea0 100644 --- a/src/DrupalPatchUtils/DoFormBase.php +++ b/src/DrupalPatchUtils/DoFormBase.php @@ -7,6 +7,7 @@ namespace DrupalPatchUtils; +use Symfony\Component\DomCrawler\Field\ChoiceFormField; use Symfony\Component\DomCrawler\Form; class DoFormBase { @@ -60,16 +61,61 @@ public function ensureTag($value) { public function getForm () { return $this->form; } + /** * @param integer $value + * * @return $this */ - protected function setStatus($value) { + public function setStatus($value) { $status = $this->form->get('field_issue_status[und]'); $status->setValue($value); $this->form->set($status); return $this; } + /** + * Returns the list of available components. + * + * @return array + */ + public function getComponents() { + /** @var ChoiceFormField $component_form */ + $component_form = $this->form->get('field_issue_component[und]'); + return $component_form->availableOptionValues(); + } + + public function setComponent($component) { + $component_form = $this->form->get('field_issue_component[und]'); + $component_form->setValue($component); + $this->form->set($component_form); + return $this; + } + + /** + * Returns the list of available versions. + * + * @return string[] + */ + public function getVersions() { + /** @var ChoiceFormField $version_form */ + $version_form = $this->form->get('field_issue_version[und]'); + return $version_form->availableOptionValues(); + } + + public function setVersion($version) { + $version_form = $this->form->get('field_issue_version[und]'); + $version_form->setValue($version); + $this->form->set($version_form); + return $this; + } + + public function setCategory($category) { + $category_form = $this->form->get('field_issue_category[und]'); + $category_form->setValue($category); + $this->form->set($category_form); + return $this; + } + } diff --git a/src/DrupalPatchUtils/IssueForm.php b/src/DrupalPatchUtils/IssueForm.php index eb0117a..5a42219 100644 --- a/src/DrupalPatchUtils/IssueForm.php +++ b/src/DrupalPatchUtils/IssueForm.php @@ -18,49 +18,6 @@ public function setTitle($title) { return $this; } - /** - * Returns the list of available components. - * - * @return array - */ - public function getComponents() { - /** @var ChoiceFormField $component_form */ - $component_form = $this->form->get('field_issue_component[und]'); - return $component_form->availableOptionValues(); - } - - public function setComponent($component) { - $component_form = $this->form->get('field_issue_component[und]'); - $component_form->setValue($component); - $this->form->set($component_form); - return $this; - } - - /** - * Returns the list of available versions. - * - * @return string[] - */ - public function getVersions() { - /** @var ChoiceFormField $version_form */ - $version_form = $this->form->get('field_issue_version[und]'); - return $version_form->availableOptionValues(); - } - - public function setVersion($version) { - $version_form = $this->form->get('field_issue_version[und]'); - $version_form->setValue($version); - $this->form->set($version_form); - return $this; - } - - public function setCategory($category) { - $category_form = $this->form->get('field_issue_category[und]'); - $category_form->setValue($category); - $this->form->set($category_form); - return $this; - } - public function setBody($body) { $body_form = $this->form->get('body[und][0][value]'); $body_form->setValue($body); From 863fb6acc479d8947b738fe78f7e4bcde3f1eeab Mon Sep 17 00:00:00 2001 From: Daniel Wehner Date: Sat, 10 Jan 2015 20:10:44 +0100 Subject: [PATCH 3/9] make it possible to set the tags --- src/DrupalPatchUtils/DoFormBase.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/DrupalPatchUtils/DoFormBase.php b/src/DrupalPatchUtils/DoFormBase.php index 1182ea0..2c43a1e 100644 --- a/src/DrupalPatchUtils/DoFormBase.php +++ b/src/DrupalPatchUtils/DoFormBase.php @@ -117,5 +117,34 @@ public function setCategory($category) { return $this; } + /** + * Returns the list of tags separated. + * + * @return string[] + */ + public function getTags() { + $tag_form = $this->form->get('taxonomy_vocabulary_9[und]'); + $tags = $tag_form->getValue(); + $tags = explode(', ', $tags); + + return $tags; + } + + /** + * Sets the tags of an issue. + * + * @param string[] $tags + * The tags as array. + * + * @return $this + */ + public function setTags(array $tags) { + $tag_form = $this->form->get('taxonomy_vocabulary_9[und]'); + + $tag_form->setValue(implode(', ', $tags)); + + return $this; + } + } From 2b25b55624ecd53657217e7abdc4671c58fc88fb Mon Sep 17 00:00:00 2001 From: Daniel Wehner Date: Fri, 16 Jan 2015 19:02:16 +0100 Subject: [PATCH 4/9] initial version --- dop | 2 + .../Command/PostIssueComment.php | 57 ++++++ src/DrupalPatchUtils/CommentEditor.php | 70 +++++++ src/DrupalPatchUtils/DoFormBase.php | 8 + src/DrupalPatchUtils/Issue.php | 24 ++- src/DrupalPatchUtils/IssueStatus.php | 189 ++++++++++++++++++ 6 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 src/DrupalPatchUtils/Command/PostIssueComment.php create mode 100644 src/DrupalPatchUtils/CommentEditor.php create mode 100644 src/DrupalPatchUtils/IssueStatus.php diff --git a/dop b/dop index 599c0ec..277df92 100755 --- a/dop +++ b/dop @@ -8,6 +8,7 @@ use DrupalPatchUtils\Command\CreateIssue; use DrupalPatchUtils\Command\Login; use DrupalPatchUtils\Command\Logout; use DrupalPatchUtils\Command\PostComment; +use DrupalPatchUtils\Command\PostIssueComment; use DrupalPatchUtils\Command\SearchIssuePatch; use DrupalPatchUtils\Command\SearchRtbcPatches; use DrupalPatchUtils\Command\ValidatePatch; @@ -23,6 +24,7 @@ $application->add(new SearchIssuePatch()); $application->add(new SearchRtbcPatches()); $application->add(new ValidatePatch()); $application->add(new ValidateRtbcPatches()); +$application->add(new PostIssueComment()); $application->add(new Login()); $application->add(new Logout()); $application->run(); diff --git a/src/DrupalPatchUtils/Command/PostIssueComment.php b/src/DrupalPatchUtils/Command/PostIssueComment.php new file mode 100644 index 0000000..c9d5c3a --- /dev/null +++ b/src/DrupalPatchUtils/Command/PostIssueComment.php @@ -0,0 +1,57 @@ +setName('postIssueComment') + ->setAliases(array('pic')) + ->setDescription('Posts comment on an issue to d.o.') + ->addArgument( + 'url', + InputArgument::REQUIRED, + 'What is the url/nid of the issue to retrieve?' + ) + ->addArgument( + 'files', + InputArgument::IS_ARRAY, + 'Files' + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $url = $input->getArgument('url'); + $issue = $this->getIssue($url); + + $browser = new DoBrowser(); + $this->ensureUserIsLoggedIn($browser, $output); + + $comment_form = $browser->getCommentForm($issue->getUri()); + + $comment_editor = new CommentEditor($comment_form); + print $comment_editor->generateContent($issue, $input->getArgument('files')); + return; + + $comment_form->setCommentText('Added comment.'); + + $browser->submitForm($comment_form->getForm()); + } + +} diff --git a/src/DrupalPatchUtils/CommentEditor.php b/src/DrupalPatchUtils/CommentEditor.php new file mode 100644 index 0000000..796b956 --- /dev/null +++ b/src/DrupalPatchUtils/CommentEditor.php @@ -0,0 +1,70 @@ +commentForm = $comment_form; + } + + public function generateContent(Issue $issue, $new_files = []) + { + $output = []; + + $output[] = "# Please enter the comment message for your changes. Lines starting"; + $output[] = "# with '#' will be ignored, and an empty message aborts the comment."; + $output[] = '#'; + $output[] = '# Comment on issue #' . $issue->getNid() . ': ' . $issue->getTitle(); + + if (!empty($new_files)) { + $output[] = '#'; + $output[] = '# Attached files'; + foreach ($new_files as $filename) { + $output[] = '# - ' . $filename; + } + } + + $output[] = '#'; + $output[] = '# Status: ' . IssueStatus::toString($this->commentForm->getStatus()); + foreach (IssueStatus::getDefinition() as $definition) { + $output[] = '# - ' . $definition['label'] . ' - ' . implode(', ', $definition['aliases']); + } + + $output[] = '#'; + $output[] = '# Priority: ' . $this->commentForm->getPriority(); +// if (isset($issue_settings['priority'])) { +// foreach (IssuePriority::getDefinition() as $definition) { +// $output[] = '# - ' . $definition['label'] . ' - ' . implode(', ', $definition['aliases']); +// } +// } + + $output[] = '#'; + $output[] = '# Tags: ' . implode(', ', $this->commentForm->getTags()); + + return implode("\n", $output); + } + + public function extractContent($text) + { + + } + + protected function filterInvalidLines(array $lines) + { + + } + +} diff --git a/src/DrupalPatchUtils/DoFormBase.php b/src/DrupalPatchUtils/DoFormBase.php index 2c43a1e..44db47b 100644 --- a/src/DrupalPatchUtils/DoFormBase.php +++ b/src/DrupalPatchUtils/DoFormBase.php @@ -74,6 +74,14 @@ public function setStatus($value) { return $this; } + public function getStatus() { + return $this->form->get('field_issue_status[und]')->getValue(); + } + + public function getPriority() { + return $this->form->get('field_issue_priority[und]')->getValue(); + } + /** * Returns the list of available components. * diff --git a/src/DrupalPatchUtils/Issue.php b/src/DrupalPatchUtils/Issue.php index 3ba9070..e952ae5 100644 --- a/src/DrupalPatchUtils/Issue.php +++ b/src/DrupalPatchUtils/Issue.php @@ -16,6 +16,13 @@ class Issue { */ protected $uri; + /** + * @var \Symfony\Component\DomCrawler\Crawler + */ + protected $crawler; + + protected $title; + /** * @param string $issue_id * NID or URI of an issue. @@ -27,9 +34,24 @@ public function __construct($issue_id) { elseif (filter_var($issue_id, FILTER_VALIDATE_URL) !== false) { $this->uri = $issue_id; } + $this->nid = str_replace('https://drupal.org/node/', '', $this->uri); + $this->getIssue(); } + public function getNid() { + return $this->nid; + } + + public function getTitle() { + if (!isset($this->title)) { + $this->getIssue(); + $this->title = $this->crawler->filter('h1')->first()->text(); + } + + return $this->title; + } + protected function getIssue() { $doBrowser = new DoBrowser(); // Get guzzle client. @@ -100,4 +122,4 @@ public function hasPatch() { } return FALSE; } -} \ No newline at end of file +} diff --git a/src/DrupalPatchUtils/IssueStatus.php b/src/DrupalPatchUtils/IssueStatus.php new file mode 100644 index 0000000..e7e7a4d --- /dev/null +++ b/src/DrupalPatchUtils/IssueStatus.php @@ -0,0 +1,189 @@ + array( + 'label' => 'Active', + 'aliases' => array( + 'active', + 'a', + ), + ), + self::NEEDS_WORK => array( + 'label' => 'Needs work', + 'aliases' => array( + 'needs work', + 'nw', + 'work', + ), + ), + self::NEEDS_REVIEW => array( + 'label' => 'Needs review', + 'aliases' => array( + 'needs review', + 'nr', + 'review', + ), + ), + self::RTBC => array( + 'label' => 'Reviewed & tested by the community', + 'aliases' => array( + 'rtbc', + '+1', + ), + ), + self::PATCH_TO_BE_PORTED => array( + 'label' => 'Patch (to be ported)', + 'aliases' => array( + 'pp', + ), + ), + self::FIXED => array( + 'label' => 'Fixed', + 'aliases' => array( + 'fixed', + 'f', + ), + ), + self::POSTPONED => array( + 'label' => 'Postponed', + 'aliases' => array( + 'p', + ), + ), + self::POSTPONED_MAINTAINER_INFO => array( + 'label' => 'Postponed (maintainer needs more info)', + 'aliases' => array( + 'pmi', + ), + ), + self::CLOSED_DUPLICATE => array( + 'label' => 'Closed (duplicate)', + 'aliases' => array( + 'cd', + 'dup', + ), + ), + self::CLOSED_WONT_FIX => array( + 'label' => "Closed (won't fix)", + 'aliases' => array( + 'cwf', + ), + ), + self::CLOSED_WORKS_AS_DESIGNED => array( + 'label' => 'Closed (works as designed)', + 'aliases' => array( + 'cwad', + ), + ), + self::CLOSED_CANNOT_REPRODUCE => array( + 'label' => 'Closed (cannot reproduce)', + 'aliases' => array( + 'cnr', + ), + ), + self::CLOSED_FIXED => array( + 'label' => 'Closed (fixed)', + 'aliases' => array( + 'cf', + ), + ), + ); + } + + public static function aliasMapReverse() { + $map = self::getDefinition(); + $aliases = array(); + foreach ($map as $status => $definition) { + $aliases[$definition['label']] = $status; + $aliases = array_merge($aliases, array_fill_keys($definition['aliases'], $status)); + } + return $aliases; + } + + public static function toInteger($string) { + $string = trim($string); + if (is_numeric($string)) { + return $string; + } + $map = self::aliasMapReverse(); + return isset($map[$string]) ? $map[$string] : FALSE; + } + + public static function toString($integer) { + return static::getDefinition()[$integer]['label']; + } + +} From 786c0c4103e27a7940b99349fc7d6cb6ab7c9900 Mon Sep 17 00:00:00 2001 From: Daniel Wehner Date: Fri, 16 Jan 2015 19:11:10 +0100 Subject: [PATCH 5/9] add editor helper --- src/DrupalPatchUtils/Command/CreateIssue.php | 19 ++------- src/DrupalPatchUtils/TextEditor.php | 42 ++++++++++++++++++++ 2 files changed, 46 insertions(+), 15 deletions(-) create mode 100644 src/DrupalPatchUtils/TextEditor.php diff --git a/src/DrupalPatchUtils/Command/CreateIssue.php b/src/DrupalPatchUtils/Command/CreateIssue.php index edfffca..02279eb 100644 --- a/src/DrupalPatchUtils/Command/CreateIssue.php +++ b/src/DrupalPatchUtils/Command/CreateIssue.php @@ -9,6 +9,7 @@ use DrupalPatchUtils\DoBrowser; use DrupalPatchUtils\IssueSummaryTemplate; +use DrupalPatchUtils\TextEditor; use DrupalPatchUtils\Uuid; use Symfony\Component\Console\Helper\DialogHelper; use Symfony\Component\Console\Input\InputArgument; @@ -72,21 +73,8 @@ protected function execute(InputInterface $input, OutputInterface $output) // Allow to input the main body either via an editor or in the shell. if ($input->getOption('editor')) { - $temp_file = '/tmp/' . Uuid::generate() . ".txt"; - $filesystem = new Filesystem(); - $filesystem->touch($temp_file); - $filesystem->dumpFile($temp_file, IssueSummaryTemplate::BODY); - - $process = new Process(sprintf('vi %s', $temp_file), NULL, NULL, NULL, 3600); - - $process->setTty(TRUE); - $process->start(); - $process->wait(); - - $output->writeln($process->getOutput()); - $output->writeln($process->getErrorOutput()); - - $body_text = file_get_contents($temp_file); + $editor = new TextEditor(); + $body_text = $editor->editor($output, IssueSummaryTemplate::BODY); } else { $body_text = $dialog->ask($output, 'Enter body: ', 'TODO'); @@ -115,4 +103,5 @@ protected function execute(InputInterface $input, OutputInterface $output) return; } + } diff --git a/src/DrupalPatchUtils/TextEditor.php b/src/DrupalPatchUtils/TextEditor.php new file mode 100644 index 0000000..a0d02ac --- /dev/null +++ b/src/DrupalPatchUtils/TextEditor.php @@ -0,0 +1,42 @@ +touch($temp_file); + $filesystem->dumpFile($temp_file, $text); + + $process = new Process(sprintf('vi %s', $temp_file), null, null, null, + 3600); + + $process->setTty(true); + $process->start(); + $process->wait(); + + $output->writeln($process->getOutput()); + $output->writeln($process->getErrorOutput()); + + $body_text = file_get_contents($temp_file); + return $body_text; + } + +} From c989ea6f24d90def87ec121209a0447d7f7736df Mon Sep 17 00:00:00 2001 From: Florian Weber Date: Fri, 16 Jan 2015 19:24:17 +0100 Subject: [PATCH 6/9] Replace drupal.org with www.drupal.org --- src/DrupalPatchUtils/DoBrowser.php | 8 ++++---- src/DrupalPatchUtils/Issue.php | 4 ++-- src/DrupalPatchUtils/RtbcQueue.php | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/DrupalPatchUtils/DoBrowser.php b/src/DrupalPatchUtils/DoBrowser.php index 30b02e0..c6edd88 100644 --- a/src/DrupalPatchUtils/DoBrowser.php +++ b/src/DrupalPatchUtils/DoBrowser.php @@ -36,14 +36,14 @@ public function __construct() { * @return bool */ public function loggedIn() { - $crawler = $this->client->request('GET', 'https://drupal.org/user/'); + $crawler = $this->client->request('GET', 'https://www.drupal.org/user/'); $log_in_button = $crawler->selectButton('Log in'); return $log_in_button->count() == 0; } public function login($user, $pass) { - $crawler = $this->client->request('GET', 'https://drupal.org/user/'); + $crawler = $this->client->request('GET', 'https://www.drupal.org/user/'); // Check if already logged in. if (($select_button = $crawler->selectButton('Log in')) && $select_button->count()) { $form = $select_button->form(); @@ -60,7 +60,7 @@ public function login($user, $pass) { public function logout() { if ($this->loggedIn()) { - $this->client->request('GET', 'https://drupal.org/user/logout'); + $this->client->request('GET', 'https://www.drupal.org/user/logout'); } } @@ -74,7 +74,7 @@ public function getCommentForm($issue_uri) { } public function getIssueForm($project) { - $uri = 'https://drupal.org/' . 'node/add/project-issue/' . $project; + $uri = 'https://www.drupal.org/' . 'node/add/project-issue/' . $project; $crawler = $this->client->request('GET', $uri); return new IssueForm($crawler->selectButton('Save')->form()); } diff --git a/src/DrupalPatchUtils/Issue.php b/src/DrupalPatchUtils/Issue.php index e952ae5..3728c57 100644 --- a/src/DrupalPatchUtils/Issue.php +++ b/src/DrupalPatchUtils/Issue.php @@ -29,12 +29,12 @@ class Issue { */ public function __construct($issue_id) { if (is_numeric($issue_id)) { - $this->uri = 'https://drupal.org/node/' . $issue_id; + $this->uri = 'https://www.drupal.org/node/' . $issue_id; } elseif (filter_var($issue_id, FILTER_VALIDATE_URL) !== false) { $this->uri = $issue_id; } - $this->nid = str_replace('https://drupal.org/node/', '', $this->uri); + $this->nid = str_replace('https://www.drupal.org/node/', '', $this->uri); $this->getIssue(); } diff --git a/src/DrupalPatchUtils/RtbcQueue.php b/src/DrupalPatchUtils/RtbcQueue.php index beae3af..2816c24 100644 --- a/src/DrupalPatchUtils/RtbcQueue.php +++ b/src/DrupalPatchUtils/RtbcQueue.php @@ -16,7 +16,7 @@ class RtbcQueue { - const DEFAULT_URI = 'https://drupal.org/project/issues/drupal?status=14&version=8.x&text=&priorities=All&categories=All&component=All&order=last_comment_timestamp&sort=asc'; + const DEFAULT_URI = 'https://www.drupal.org/project/issues/drupal?status=14&version=8.x&text=&priorities=All&categories=All&component=All&order=last_comment_timestamp&sort=asc'; /** * @var \Guzzle\Http\Url @@ -80,4 +80,4 @@ protected function getPage() { } return $crawler; } -} \ No newline at end of file +} From f6e9ebace95d81cef14c7ee28ab19ea4fa59eb0d Mon Sep 17 00:00:00 2001 From: Florian Weber Date: Fri, 16 Jan 2015 19:53:27 +0100 Subject: [PATCH 7/9] Make PostIssueComment work. --- .../Command/PostIssueComment.php | 39 ++++++++++-- src/DrupalPatchUtils/CommentEditor.php | 38 +++++++++++- src/DrupalPatchUtils/CommentForm.php | 3 - src/DrupalPatchUtils/DoFormBase.php | 12 ++++ src/DrupalPatchUtils/IssueMetadata.php | 47 ++++++++++++++ src/DrupalPatchUtils/IssuePriority.php | 62 +++++++++++++++++++ src/DrupalPatchUtils/IssueStatus.php | 32 ++-------- 7 files changed, 198 insertions(+), 35 deletions(-) create mode 100644 src/DrupalPatchUtils/IssueMetadata.php create mode 100644 src/DrupalPatchUtils/IssuePriority.php diff --git a/src/DrupalPatchUtils/Command/PostIssueComment.php b/src/DrupalPatchUtils/Command/PostIssueComment.php index c9d5c3a..d369685 100644 --- a/src/DrupalPatchUtils/Command/PostIssueComment.php +++ b/src/DrupalPatchUtils/Command/PostIssueComment.php @@ -11,8 +11,12 @@ use DrupalPatchUtils\CommentEditor; use DrupalPatchUtils\DoBrowser; +use DrupalPatchUtils\IssuePriority; +use DrupalPatchUtils\IssueStatus; +use DrupalPatchUtils\TextEditor; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\OutputInterface; class PostIssueComment extends CommandBase { @@ -37,6 +41,10 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { + if (!$output instanceof ConsoleOutputInterface) { + throw new \Exception('Console output needed.'); + } + $url = $input->getArgument('url'); $issue = $this->getIssue($url); @@ -46,12 +54,35 @@ protected function execute(InputInterface $input, OutputInterface $output) $comment_form = $browser->getCommentForm($issue->getUri()); $comment_editor = new CommentEditor($comment_form); - print $comment_editor->generateContent($issue, $input->getArgument('files')); - return; + $template = $comment_editor->generateContent($issue, $input->getArgument('files')); + + $editor = new TextEditor(); + $result = $editor->editor($output, $template); + + $body = $comment_editor->getCommentText($result); + $metadata = $comment_editor->getMetadata($result); + + $comment_form->setCommentText($body); - $comment_form->setCommentText('Added comment.'); + if (isset($metadata['status'])) { + $comment_form->setStatus(IssueStatus::toInteger($metadata['status'])); + } - $browser->submitForm($comment_form->getForm()); + if (isset($metadata['priority'])) { + $comment_form->setPriority(IssuePriority::toInteger($metadata['priority'])); + } + + $crawler = $browser->submitForm($comment_form->getForm()); + + if ($errors = $browser->getErrors($crawler)) { + $output->getErrorOutput()->writeln($errors); + } + else { + $uri = $browser->getClient()->getHistory()->current()->getUri(); + $output->writeln(sprintf('Posting the issue was successful: %s', $uri)); + } + + return; } } diff --git a/src/DrupalPatchUtils/CommentEditor.php b/src/DrupalPatchUtils/CommentEditor.php index 796b956..d9cfac4 100644 --- a/src/DrupalPatchUtils/CommentEditor.php +++ b/src/DrupalPatchUtils/CommentEditor.php @@ -8,7 +8,8 @@ namespace DrupalPatchUtils; -class CommentEditor { +class CommentEditor +{ /** * @var \DrupalPatchUtils\CommentForm @@ -40,7 +41,8 @@ public function generateContent(Issue $issue, $new_files = []) $output[] = '#'; $output[] = '# Status: ' . IssueStatus::toString($this->commentForm->getStatus()); foreach (IssueStatus::getDefinition() as $definition) { - $output[] = '# - ' . $definition['label'] . ' - ' . implode(', ', $definition['aliases']); + $output[] = '# - ' . $definition['label'] . ' - ' . implode(', ', + $definition['aliases']); } $output[] = '#'; @@ -67,4 +69,36 @@ protected function filterInvalidLines(array $lines) } + public function getCommentText($lines) + { + $array = explode("\n", $lines); + $lines = array_filter($array, function ($value) { + return !(isset($value[0]) && $value[0] == '#'); + }); + + return implode("\n", $lines); + } + + public function getMetadata($lines) + { + $metadata = array(); + foreach (explode(PHP_EOL, $lines) as $line) { + if (strpos($line, '# Tags:') === 0) { + $metadata['tags'] = trim(str_replace('# Tags: ', '', $line)); + } + if (strpos($line, '# Status:') === 0) { + $status = trim(str_replace('# Status: ', '', $line)); + + $metadata['status'] = $status; + } + if (strpos($line, '# Priority:') === 0) { + $priority = trim(str_replace('# Priority: ', '', $line)); + + $metadata['priority'] = $priority; + } + } + + return $metadata; + } + } diff --git a/src/DrupalPatchUtils/CommentForm.php b/src/DrupalPatchUtils/CommentForm.php index fed0ddb..5648fe6 100644 --- a/src/DrupalPatchUtils/CommentForm.php +++ b/src/DrupalPatchUtils/CommentForm.php @@ -9,9 +9,6 @@ namespace DrupalPatchUtils; - -use Symfony\Component\DomCrawler\Form; - class CommentForm extends DoFormBase { public function setCommentText($text) { diff --git a/src/DrupalPatchUtils/DoFormBase.php b/src/DrupalPatchUtils/DoFormBase.php index 44db47b..b7c9ef7 100644 --- a/src/DrupalPatchUtils/DoFormBase.php +++ b/src/DrupalPatchUtils/DoFormBase.php @@ -82,6 +82,18 @@ public function getPriority() { return $this->form->get('field_issue_priority[und]')->getValue(); } + /** + * @param integer $value + * + * @return $this + */ + public function setPriority($value) { + $status = $this->form->get('field_issue_priority[und]'); + $status->setValue($value); + $this->form->set($status); + return $this; + } + /** * Returns the list of available components. * diff --git a/src/DrupalPatchUtils/IssueMetadata.php b/src/DrupalPatchUtils/IssueMetadata.php new file mode 100644 index 0000000..833ac8a --- /dev/null +++ b/src/DrupalPatchUtils/IssueMetadata.php @@ -0,0 +1,47 @@ + $definition) { + $aliases[$definition['label']] = $status; + $aliases = array_merge($aliases, array_fill_keys($definition['aliases'], $status)); + } + + return $aliases; + } + + public static function toInteger($string) + { + $string = trim($string); + if (is_numeric($string)) { + return (string) $string; + } + $map = static::aliasMapReverse(); + + return isset($map[$string]) ? (string) $map[$string] : false; + } + + public static function toString($integer) + { + return static::getDefinition()[$integer]['label']; + } + + +} diff --git a/src/DrupalPatchUtils/IssuePriority.php b/src/DrupalPatchUtils/IssuePriority.php new file mode 100644 index 0000000..73c2d2c --- /dev/null +++ b/src/DrupalPatchUtils/IssuePriority.php @@ -0,0 +1,62 @@ + array( + 'label' => 'Critical', + 'aliases' => array( + 'critical', + 'crit', + 'c', + ), + ), + static::MAJOR => array( + 'label' => 'Major', + 'aliases' => array( + 'major', + 'maj', + 'ma', + ), + ), + static::NORMAL => array( + 'label' => 'Normal', + 'aliases' => array( + 'normal', + 'norm', + 'n', + ), + ), + static::MINOR => array( + 'label' => 'Minor', + 'aliases' => array( + 'minor', + 'min', + 'mi', + ), + ), + ); + } + +} diff --git a/src/DrupalPatchUtils/IssueStatus.php b/src/DrupalPatchUtils/IssueStatus.php index e7e7a4d..9adde59 100644 --- a/src/DrupalPatchUtils/IssueStatus.php +++ b/src/DrupalPatchUtils/IssueStatus.php @@ -10,7 +10,8 @@ /** * Defines drupal.org issue statuses. */ -class IssueStatus { +class IssueStatus extends IssueMetadata +{ /* 1 Active @@ -59,7 +60,8 @@ class IssueStatus { * * @return array */ - public static function getOpenIssues() { + public static function getOpenIssues() + { return array( self::ACTIVE, self::NEEDS_WORK, @@ -72,7 +74,8 @@ public static function getOpenIssues() { ); } - public static function getDefinition() { + public static function getDefinition() + { return array( self::ACTIVE => array( 'label' => 'Active', @@ -163,27 +166,4 @@ public static function getDefinition() { ); } - public static function aliasMapReverse() { - $map = self::getDefinition(); - $aliases = array(); - foreach ($map as $status => $definition) { - $aliases[$definition['label']] = $status; - $aliases = array_merge($aliases, array_fill_keys($definition['aliases'], $status)); - } - return $aliases; - } - - public static function toInteger($string) { - $string = trim($string); - if (is_numeric($string)) { - return $string; - } - $map = self::aliasMapReverse(); - return isset($map[$string]) ? $map[$string] : FALSE; - } - - public static function toString($integer) { - return static::getDefinition()[$integer]['label']; - } - } From d811ecbf88e2c9ad51659592e20be486cd849914 Mon Sep 17 00:00:00 2001 From: Florian Weber Date: Fri, 16 Jan 2015 19:57:24 +0100 Subject: [PATCH 8/9] Remove unused methods --- src/DrupalPatchUtils/CommentEditor.php | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/DrupalPatchUtils/CommentEditor.php b/src/DrupalPatchUtils/CommentEditor.php index d9cfac4..c4ad0ce 100644 --- a/src/DrupalPatchUtils/CommentEditor.php +++ b/src/DrupalPatchUtils/CommentEditor.php @@ -41,34 +41,21 @@ public function generateContent(Issue $issue, $new_files = []) $output[] = '#'; $output[] = '# Status: ' . IssueStatus::toString($this->commentForm->getStatus()); foreach (IssueStatus::getDefinition() as $definition) { - $output[] = '# - ' . $definition['label'] . ' - ' . implode(', ', - $definition['aliases']); + $output[] = '# - ' . $definition['label'] . ' - ' . implode(', ', $definition['aliases']); } $output[] = '#'; - $output[] = '# Priority: ' . $this->commentForm->getPriority(); -// if (isset($issue_settings['priority'])) { -// foreach (IssuePriority::getDefinition() as $definition) { -// $output[] = '# - ' . $definition['label'] . ' - ' . implode(', ', $definition['aliases']); -// } -// } + $output[] = '# Priority: ' . IssuePriority::toString($this->commentForm->getPriority()); + foreach (IssuePriority::getDefinition() as $definition) { + $output[] = '# - ' . $definition['label'] . ' - ' . implode(', ', $definition['aliases']); + } $output[] = '#'; $output[] = '# Tags: ' . implode(', ', $this->commentForm->getTags()); return implode("\n", $output); } - - public function extractContent($text) - { - - } - - protected function filterInvalidLines(array $lines) - { - - } - + public function getCommentText($lines) { $array = explode("\n", $lines); From 62c52c77d1d23d662602a7395cff839158b798c6 Mon Sep 17 00:00:00 2001 From: Daniel Wehner Date: Mon, 19 Jan 2015 13:06:07 +0100 Subject: [PATCH 9/9] File upload works now --- .../Command/PostIssueComment.php | 7 ++- src/DrupalPatchUtils/CommentForm.php | 55 ++++++++++++++++--- src/DrupalPatchUtils/DoBrowser.php | 4 +- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/DrupalPatchUtils/Command/PostIssueComment.php b/src/DrupalPatchUtils/Command/PostIssueComment.php index d369685..f5c45ed 100644 --- a/src/DrupalPatchUtils/Command/PostIssueComment.php +++ b/src/DrupalPatchUtils/Command/PostIssueComment.php @@ -53,8 +53,11 @@ protected function execute(InputInterface $input, OutputInterface $output) $comment_form = $browser->getCommentForm($issue->getUri()); + + $files = $input->getArgument('files'); + $comment_editor = new CommentEditor($comment_form); - $template = $comment_editor->generateContent($issue, $input->getArgument('files')); + $template = $comment_editor->generateContent($issue, $files); $editor = new TextEditor(); $result = $editor->editor($output, $template); @@ -62,6 +65,8 @@ protected function execute(InputInterface $input, OutputInterface $output) $body = $comment_editor->getCommentText($result); $metadata = $comment_editor->getMetadata($result); + $comment_form->uploadFiles($files); + $comment_form->setCommentText($body); if (isset($metadata['status'])) { diff --git a/src/DrupalPatchUtils/CommentForm.php b/src/DrupalPatchUtils/CommentForm.php index 5648fe6..c701ea0 100644 --- a/src/DrupalPatchUtils/CommentForm.php +++ b/src/DrupalPatchUtils/CommentForm.php @@ -1,4 +1,5 @@ browser = $browser; + $this->form = $this->getCrawler()->selectButton('Save')->form(); + } + + public function setCommentText($text) + { + $comment = $this->form->get('nodechanges_comment_body[value]'); + $comment->setValue($text); + $this->form->set($comment); + return $this; + } + + public function uploadFiles(array $files = []) + { + $file_nr = 0; + foreach ($files as $key => $file) { + $this->form = $this->getCrawler()->selectButton('Upload')->form(); + + while (!($this->form->has("files[field_issue_files_und_$file_nr]"))) { + $file_nr++; + } + $this->form["files[field_issue_files_und_$file_nr]"]->setFilePath($file); + + $this->browser->getClient()->submit($this->form); + } + + $this->form = $this->getCrawler()->selectButton('Save')->form(); + } - public function setCommentText($text) { - $comment = $this->form->get('nodechanges_comment_body[value]'); - $comment->setValue($text); - $this->form->set($comment); - return $this; - } + /** + * @return null|\Symfony\Component\DomCrawler\Crawler + */ + protected function getCrawler() + { + return $this->browser->getClient()->getCrawler(); + } } diff --git a/src/DrupalPatchUtils/DoBrowser.php b/src/DrupalPatchUtils/DoBrowser.php index c6edd88..0b18caa 100644 --- a/src/DrupalPatchUtils/DoBrowser.php +++ b/src/DrupalPatchUtils/DoBrowser.php @@ -69,8 +69,8 @@ public function logout() { * @return \DrupalPatchUtils\CommentForm */ public function getCommentForm($issue_uri) { - $crawler = $this->client->request('GET', $issue_uri . '/edit'); - return new CommentForm($crawler->selectButton('Save')->form()); + $this->client->request('GET', $issue_uri . '/edit'); + return new CommentForm($this); } public function getIssueForm($project) {