{"action":"created","comment":{"url":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/comments/60433809","id":60433809,"diff_hunk":"@@ -0,0 +1,690 @@\n+<?php\n+\n+namespace Pim\\Behat\\Decorator;\n+\n+use Behat\\Mink\\Element\\Element;\n+use Behat\\Mink\\Element\\NodeElement;\n+use Behat\\Mink\\Exception\\ElementNotFoundException;\n+use Behat\\Mink\\Exception\\ExpectationException;\n+use Context\\Spin\\SpinCapableTrait;\n+\n+/**\n+ * @author    Adrien Pétremann <adrien.petremann@akeneo.com>\n+ * @copyright 2016 Akeneo SAS (http://www.akeneo.com)\n+ * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)\n+ */\n+class InputDecorator extends ElementDecorator\n+{\n+    use SpinCapableTrait;\n+\n+    /*\n+     * The Text inputs selectors contains an EE selector.\n+     * This should not be declared here, but we wait for the Decorators refactoring to choose where to declare it..\n+     * TODO Move .asset-collection-picker into EE.\n+     */\n+    protected $selectors = [\n+        'Input label' => ['css' => '.field-container header label:contains(\"%s\")'],\n+        'Text inputs' => ['css' => '.field-input input, .field-input textarea, .field-input .asset-collection-picker'],\n+    ];\n+\n+    /**\n+     * @param string $label\n+     * @param bool   $copy\n+     *\n+     * @throws ElementNotFoundException\n+     *\n+     * @return NodeElement\n+     */\n+    public function findField($label, $copy = false)\n+    {\n+        if (1 === preg_match('/ in (.{1,3})$/', $label)) {\n+            // Price in EUR\n+            list($label, $currency) = explode(' in ', $label);\n+            $fieldContainer = $this->findFieldContainer($label);\n+\n+            return $this->findCompoundField($fieldContainer, $currency);\n+        }\n+\n+        $subContainer = $this->spin(function () use ($label, $copy) {\n+            return $this->findFieldContainer($label)\n+                ->find('css', $copy ? '.copy-container .form-field' : '.form-field');\n+        });\n+\n+        $field = $this->spin(function () use ($subContainer) {\n+            return $subContainer->find('css', '.field-input input, .field-input textarea');\n+        });\n+\n+        return $field;\n+    }\n+\n+    /**\n+     * Find field container\n+     *\n+     * @param string $label\n+     *\n+     * @throws ElementNotFoundException\n+     *\n+     * @return NodeElement\n+     */\n+    public function findFieldContainer($label)\n+    {\n+        $matches = null;\n+        if (preg_match('/^(?P<amount>.*) in [A-Z]{1,3}$/', $label, $matches)) {\n+            // Match \"Price in EUR\" to have \"Price\" as label.\n+            $label = $matches['amount'];\n+        }\n+\n+        $selector = sprintf($this->selectors['Input label']['css'], $label);\n+\n+        $labelNode = $this->spin(function () use ($label, $selector) {\n+            return $this->find('css', $selector);\n+        }, sprintf('Cannot find the input label \"%s\" (%s)', $label, $selector));\n+\n+        $container = $this->spin(function () use ($labelNode) {\n+            return $labelNode->getParent()->getParent()->getParent();\n+        });\n+\n+        $container->name = $label;\n+\n+        return $container;\n+    }\n+\n+    /**\n+     * This method allows to fill a field by passing the label\n+     *\n+     * @param string  $label\n+     * @param string  $value\n+     * @param Element $element\n+     *\n+     * @throws ElementNotFoundException\n+     */\n+    public function fillField($label, $value, Element $element = null)\n+    {\n+        $isLabel = false;\n+\n+        try {\n+            $fieldContainer = $this->findFieldContainer($label);\n+        } catch (ElementNotFoundException $e) {\n+            $isLabel        = true;\n+            $fieldContainer = $this->extractLabelElement($label, $element);\n+        }\n+\n+        $fieldType = $this->getFieldType($fieldContainer, $isLabel);\n+\n+        switch ($fieldType) {\n+            case 'text':\n+            case 'date':\n+            case 'number':\n+                $this->fillTextField($fieldContainer, $value);\n+                break;\n+            case 'textArea':\n+                $this->fillTextAreaField($fieldContainer, $value);\n+                break;\n+            case 'metric':\n+                $this->fillMetricField($fieldContainer, $value);\n+                break;\n+            case 'multiSelect':\n+                $this->fillMultiSelectField($fieldContainer, $value);\n+                break;\n+            case 'price':\n+                $this->fillPriceField($fieldContainer, $value);\n+                break;\n+            case 'select':\n+                $this->fillSelectField($fieldContainer, $value);\n+                break;\n+            default:\n+                throw new ElementNotFoundException($this->getSession());\n+        }\n+    }\n+\n+    /**\n+     * Fills a text field element with $value, identified by its container or label.\n+     *\n+     * @param NodeElement $fieldContainerOrLabel\n+     * @param string      $value\n+     *\n+     * @throws ElementNotFoundException\n+     */\n+    protected function fillTextField(NodeElement $fieldContainerOrLabel, $value)\n+    {\n+        $field = $fieldContainerOrLabel->find('css', 'div.field-input input');\n+\n+        // no field found, we're using a label\n+        if (null === $field) {\n+            $field = $fieldContainerOrLabel->getParent()->getParent()->find('css', 'div.field-input input');\n+        }\n+\n+        if (null === $field) {\n+            $field = $fieldContainerOrLabel->getParent()->find('css', 'div.controls input');\n+        }\n+\n+        if (null === $field) {\n+            throw new ElementNotFoundException($this->getSession(), 'text field');\n+        }\n+\n+        $field->setValue($value);\n+        $this->getSession()->executeScript('$(\\'.field-input input[type=\"text\"]\\').trigger(\\'change\\');');\n+    }\n+\n+    /**\n+     * Find a compound field\n+     *\n+     * @param NodeElement $fieldContainer\n+     * @param             $currency\n+     *\n+     * @throws ElementNotFoundException\n+     *\n+     * @return NodeElement\n+     */\n+    protected function findCompoundField($fieldContainer, $currency)\n+    {\n+        $input = $fieldContainer->find('css', sprintf('input[data-currency=%s]', $currency));\n+\n+        if (!$input) {\n+            throw new ElementNotFoundException(\n+                $this->getSession(),\n+                'compound field',\n+                'id|name|label|value',\n+                $fieldContainer->name\n+            );\n+        }\n+\n+        return $input;\n+    }\n+\n+    /**\n+     * Fills a textarea field element with $value\n+     *\n+     * @param NodeElement $fieldContainer\n+     * @param string      $value\n+     */\n+    protected function fillTextAreaField(NodeElement $fieldContainer, $value)\n+    {\n+        $this->spin(function () use ($value, $fieldContainer) {\n+            $field = $fieldContainer->find('css', 'div.field-input > textarea');\n+\n+            if (!$field || !$field->isVisible()) {\n+                // the textarea can be hidden (display=none) when using WYSIWYG\n+                $field = $fieldContainer->find('css', 'div.note-editor > .note-editable');\n+            }\n+\n+            $field->setValue($value);\n+\n+            return ($field->getValue() === $value || $field->getHtml() === $value);\n+        });\n+\n+        $this->getSession()->executeScript('$(\\'.field-input textarea\\').trigger(\\'change\\');');\n+    }\n+\n+    /**\n+     * Fills a simple select2 field with $value\n+     *\n+     * @param NodeElement $fieldContainer\n+     * @param string      $value\n+     *\n+     * @throws ExpectationException\n+     */\n+    public function fillSelectField(NodeElement $fieldContainer, $value)\n+    {\n+        if ('' === $value || null === $value) {\n+            $emptyLink = $this->spin(function () use ($fieldContainer) {\n+                return $fieldContainer->find('css', '.select2-search-choice-close');\n+            });\n+\n+            $emptyLink->click();\n+\n+            $this->getSession()->executeScript(\n+                '$(\\'.field-input input[type=\"hidden\"].select-field\\').trigger(\\'change\\');'\n+            );\n+\n+            return;\n+        }\n+\n+        $link = $this->spin(function () use ($fieldContainer) {\n+            return $fieldContainer->find('css', 'a.select2-choice');\n+        }, sprintf('Could not find select2 widget inside %s', $fieldContainer->getParent()->getHtml()));\n+\n+\n+        $link->click();\n+\n+        $item = $this->spin(function () use ($link, $value) {\n+            return $this->getSession()->getPage()->find('css', sprintf('.select2-results li:contains(\"%s\")', $value));\n+        });\n+\n+        $item->click();\n+\n+        $this->getSession()->executeScript(\n+            '$(\\'.field-input input[type=\"hidden\"].select-field\\').trigger(\\'change\\');'\n+        );\n+\n+        return;\n+    }\n+\n+    /**\n+     * Fills a metric field with $value\n+     *\n+     * @param NodeElement $container\n+     * @param string      $value\n+     *\n+     * @throws \\InvalidArgumentException\n+     */\n+    protected function fillMetricField(NodeElement $container, $value)\n+    {\n+        if (false !== strpos($value, ' ')) {\n+            list($text, $select) = explode(' ', $value);\n+        } else {\n+            $text   = $value;\n+            $select = null;\n+        }\n+\n+        if (null !== $select) {\n+            $selector = $this->spin(function () use ($container) {\n+                return $container->find('css', 'a.select2-choice');\n+            }, sprintf('Could not find select2 widget selector inside %s', $container->getHtml()));\n+\n+            $selector->click();\n+\n+            $item = $this->spin(function () use ($select, $container) {\n+                return $container->getSession()\n+                    ->getPage()\n+                    ->find('css', sprintf('#select2-drop li:contains(\"%s\")', $select));\n+\n+            }, sprintf('Could not find select2 widget inside %s', $container->getHtml()));\n+\n+            $item->click();\n+        }\n+\n+        $this->fillTextField($container, $text);\n+    }\n+\n+    /**\n+     * Fills a select2 multi-select field with $values\n+     *\n+     *\n+     * @param NodeElement $fieldContainer\n+     * @param string      $values\n+     *\n+     * @throws \\InvalidArgumentException\n+     */\n+    protected function fillMultiSelectField(NodeElement $fieldContainer, $values)\n+    {\n+        $field = $fieldContainer->find('css', '.form-field');\n+\n+        // clear multi select first\n+        $fieldClasses = $field->getAttribute('class');\n+        if (preg_match('/akeneo-multi-select(-reference-data)?-field/', $fieldClasses, $matches)) {\n+            $select2Selector = sprintf('.%s div.field-input > input', $matches[0]);\n+            $script          = sprintf('$(\"%s\").select2(\"val\", \"\");$(\"%1$s\").trigger(\"change\");', $select2Selector);\n+            $this->getSession()->executeScript($script);\n+        }\n+\n+        $link = $fieldContainer->find('css', 'ul.select2-choices');\n+        if (null === $link) {\n+            throw new \\InvalidArgumentException(\n+                sprintf('Could not find select2 widget inside %s', $fieldContainer->getParent()->getHtml())\n+            );\n+        }\n+\n+        foreach ($this->listToArray($values) as $value) {\n+            $link->click();\n+            $item = $this->spin(function () use ($value) {\n+                return $this->getSession()\n+                    ->getPage()\n+                    ->find(\n+                        'css',\n+                        sprintf('.select2-result:not(.select2-selected) .select2-result-label:contains(\"%s\")', $value)\n+                    );\n+            });\n+\n+            // Select the value in the displayed dropdown\n+            if (null !== $item) {\n+                $item->click();\n+            } else {\n+                throw new \\InvalidArgumentException(\n+                    sprintf('Could not find select2 item with value %s inside %s', $value, $link->getHtml())\n+                );\n+            }\n+        }\n+\n+        $this->getSession()->executeScript(\n+            '$(\\'.field-input input.select-field\\').trigger(\\'change\\');'\n+        );\n+    }\n+\n+    /**\n+     * Fills a compound field with $value, by passing the $label\n+     *\n+     * @param NodeElement $fieldContainer\n+     * @param string      $value\n+     *\n+     * @throws ElementNotFoundException\n+     */\n+    protected function fillPriceField(NodeElement $fieldContainer, $value)\n+    {\n+        $amount   = null;\n+        $currency = null;\n+\n+        if (false !== strpos($value, ' ')) {\n+            list($amount, $currency) = explode(' ', $value);\n+        }\n+\n+        // it happens when we want to set an empty price\n+        if (null === $currency && null !== $value) {\n+            $currency = $value;\n+        }\n+\n+        if (null === $currency) {\n+            throw new \\InvalidArgumentException(\n+                sprintf(\n+                    'The \"%s\" field is compound but the sub label was not provided',\n+                    $fieldContainer->name\n+                )\n+            );\n+        }\n+\n+        $field = $this->findCompoundField($fieldContainer, $currency);\n+        $field->setValue($amount);\n+\n+        $this->getSession()->executeScript(\n+            '$(\\'.field-input input[type=\"text\"]\\').trigger(\\'change\\');'\n+        );\n+    }\n+\n+    /**\n+     * @param string $inputLabel\n+     * @param string $currency\n+     *\n+     * @return NodeElement\n+     */\n+    public function findCurrencyInput($inputLabel, $currency)\n+    {\n+        $fieldContainer = $this->findFieldContainer($inputLabel);\n+\n+        return $this->findCompoundField($fieldContainer, $currency);\n+    }\n+\n+    /**\n+     * Extracts and returns the label NodeElement, identified by $field content and $element\n+     *\n+     * @param string  $field\n+     * @param Element $element\n+     *\n+     * @return NodeElement\n+     */\n+    protected function extractLabelElement($field, $element)\n+    {\n+        $subLabelContent = null;\n+        $labelContent    = $field;\n+\n+        $matches = null;\n+        if (preg_match('/^(?P<subLabel>.*) (?P<label>[A-Z]{1,3})$/', $field, $matches)) {\n+            $subLabelContent = $matches['subLabel'];\n+            $labelContent    = $matches['label'];\n+        }\n+\n+        if ($element) {\n+            $label = $this->spin(function () use ($element, $labelContent) {\n+                return $element->find('css', sprintf('label:contains(\"%s\")', $labelContent));\n+            }, sprintf('unable to find label %s in element : %s', $labelContent, $element->getHtml()));\n+        } else {\n+            $label = $this->spin(function () use ($labelContent) {\n+                return $this->find('css', sprintf('label:contains(\"%s\")', $labelContent));\n+            }, sprintf('unable to find label %s', $labelContent));\n+        }\n+\n+        $label->labelContent    = $labelContent;\n+        $label->subLabelContent = $subLabelContent;\n+\n+        return $label;\n+    }\n+\n+    /**\n+     * Transform a list to array\n+     *\n+     * @param string $list\n+     *\n+     * @return array\n+     */\n+    protected function listToArray($list)\n+    {\n+        if (empty($list)) {\n+            return [];\n+        }\n+\n+        return explode(', ', str_replace(' and ', ', ', $list));\n+    }\n+\n+    /**\n+     * Guesses the type of field identified by $label and returns it.\n+     *\n+     * Possible identified fields are :\n+     * [date, metric, multiSelect, number, price, select, text, textArea]\n+     *\n+     * @param $fieldContainer\n+     *\n+     * @return string\n+     */\n+    protected function getFieldType($fieldContainer, $isLabel = false)\n+    {\n+        if (null === $fieldContainer || !$fieldContainer instanceof NodeElement) {\n+            return null;\n+        }\n+\n+        if ($isLabel) {\n+            $formFieldWrapper = $fieldContainer->getParent()->getParent();\n+        } else {\n+            $formFieldWrapper = $fieldContainer->find('css', 'div.form-field');\n+        }\n+\n+        if ($formFieldWrapper->hasClass('akeneo-datepicker-field')) {","path":"features/Pim/Behat/Decorator/InputDecorator.php","position":479,"original_position":479,"commit_id":"09b37caaaeb311cf005e606cd21fa60306cbbbfc","original_commit_id":"09b37caaaeb311cf005e606cd21fa60306cbbbfc","user":{"login":"juliensnz","id":1117272,"avatar_url":"https://avatars.githubusercontent.com/u/1117272?v=3","gravatar_id":"","url":"https://api.github.com/users/juliensnz","html_url":"https://github.com/juliensnz","followers_url":"https://api.github.com/users/juliensnz/followers","following_url":"https://api.github.com/users/juliensnz/following{/other_user}","gists_url":"https://api.github.com/users/juliensnz/gists{/gist_id}","starred_url":"https://api.github.com/users/juliensnz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juliensnz/subscriptions","organizations_url":"https://api.github.com/users/juliensnz/orgs","repos_url":"https://api.github.com/users/juliensnz/repos","events_url":"https://api.github.com/users/juliensnz/events{/privacy}","received_events_url":"https://api.github.com/users/juliensnz/received_events","type":"User","site_admin":false},"body":"IMVHO switch is way more readable in this case.","created_at":"2016-04-20T15:44:10Z","updated_at":"2016-04-20T15:44:10Z","html_url":"https://github.com/akeneo/pim-community-dev/pull/4285#discussion_r60433809","pull_request_url":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/4285","_links":{"self":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/comments/60433809"},"html":{"href":"https://github.com/akeneo/pim-community-dev/pull/4285#discussion_r60433809"},"pull_request":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/4285"}}},"pull_request":{"url":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/4285","id":65298523,"html_url":"https://github.com/akeneo/pim-community-dev/pull/4285","diff_url":"https://github.com/akeneo/pim-community-dev/pull/4285.diff","patch_url":"https://github.com/akeneo/pim-community-dev/pull/4285.patch","issue_url":"https://api.github.com/repos/akeneo/pim-community-dev/issues/4285","number":4285,"state":"open","locked":false,"title":"[PIM-5558-POC] POC to apply Product Edit Form components to Variant Groups","user":{"login":"pierallard","id":1590933,"avatar_url":"https://avatars.githubusercontent.com/u/1590933?v=3","gravatar_id":"","url":"https://api.github.com/users/pierallard","html_url":"https://github.com/pierallard","followers_url":"https://api.github.com/users/pierallard/followers","following_url":"https://api.github.com/users/pierallard/following{/other_user}","gists_url":"https://api.github.com/users/pierallard/gists{/gist_id}","starred_url":"https://api.github.com/users/pierallard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pierallard/subscriptions","organizations_url":"https://api.github.com/users/pierallard/orgs","repos_url":"https://api.github.com/users/pierallard/repos","events_url":"https://api.github.com/users/pierallard/events{/privacy}","received_events_url":"https://api.github.com/users/pierallard/received_events","type":"User","site_admin":false},"body":"Previous PR: https://github.com/akeneo/pim-community-dev/pull/4239\r\n\r\n| Q                                 | A\r\n| --------------------------------- | ---\r\n| Added Specs                       |\r\n| Added Behats                      |\r\n| Changelog updated                 |\r\n| Review and 2 GTM                  |\r\n| Micro Demo to the PO (Story only) |\r\n| Migration script                  |\r\n| Tech Doc                          |\r\n\r\n## Stuff done\r\nThis PR contains : \r\n- The POC initially made by @juliensnz to put JS elements for Variant Group\r\n- Behat adaptation for the variant group related views\r\n- POC adaptation to cleaner code\r\n\r\n## Stuff to do, not mandatory in this PR\r\n- [x] Remove `\\Pim\\Bundle\\EnrichBundle\\Controller\\VariantGroupAttributeController` ?\r\n- [ ] Delete an attribute on variant group, is shows \"There are unsaved changes.\" but is doesn't need save. There is the same bug/behaviour on Products.\r\n- [ ] There is no more flash message when deleting a variant group attribute. See if OK. But iso with products.\r\n- [ ] FR locale not enabled for user Julien, it should to be consistent.\r\n","created_at":"2016-04-05T12:49:11Z","updated_at":"2016-04-20T15:44:10Z","closed_at":null,"merged_at":null,"merge_commit_sha":"22c6b129f1cb181dc2deefe0138fd246bbae177b","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/4285/commits","review_comments_url":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/4285/comments","review_comment_url":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/comments{/number}","comments_url":"https://api.github.com/repos/akeneo/pim-community-dev/issues/4285/comments","statuses_url":"https://api.github.com/repos/akeneo/pim-community-dev/statuses/09b37caaaeb311cf005e606cd21fa60306cbbbfc","head":{"label":"akeneo:PIM-5558-poc","ref":"PIM-5558-poc","sha":"09b37caaaeb311cf005e606cd21fa60306cbbbfc","user":{"login":"akeneo","id":2510186,"avatar_url":"https://avatars.githubusercontent.com/u/2510186?v=3","gravatar_id":"","url":"https://api.github.com/users/akeneo","html_url":"https://github.com/akeneo","followers_url":"https://api.github.com/users/akeneo/followers","following_url":"https://api.github.com/users/akeneo/following{/other_user}","gists_url":"https://api.github.com/users/akeneo/gists{/gist_id}","starred_url":"https://api.github.com/users/akeneo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akeneo/subscriptions","organizations_url":"https://api.github.com/users/akeneo/orgs","repos_url":"https://api.github.com/users/akeneo/repos","events_url":"https://api.github.com/users/akeneo/events{/privacy}","received_events_url":"https://api.github.com/users/akeneo/received_events","type":"Organization","site_admin":false},"repo":{"id":5367323,"name":"pim-community-dev","full_name":"akeneo/pim-community-dev","owner":{"login":"akeneo","id":2510186,"avatar_url":"https://avatars.githubusercontent.com/u/2510186?v=3","gravatar_id":"","url":"https://api.github.com/users/akeneo","html_url":"https://github.com/akeneo","followers_url":"https://api.github.com/users/akeneo/followers","following_url":"https://api.github.com/users/akeneo/following{/other_user}","gists_url":"https://api.github.com/users/akeneo/gists{/gist_id}","starred_url":"https://api.github.com/users/akeneo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akeneo/subscriptions","organizations_url":"https://api.github.com/users/akeneo/orgs","repos_url":"https://api.github.com/users/akeneo/repos","events_url":"https://api.github.com/users/akeneo/events{/privacy}","received_events_url":"https://api.github.com/users/akeneo/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/akeneo/pim-community-dev","description":"[Community Development Repository] The open source Product Information Management (PIM)","fork":false,"url":"https://api.github.com/repos/akeneo/pim-community-dev","forks_url":"https://api.github.com/repos/akeneo/pim-community-dev/forks","keys_url":"https://api.github.com/repos/akeneo/pim-community-dev/keys{/key_id}","collaborators_url":"https://api.github.com/repos/akeneo/pim-community-dev/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/akeneo/pim-community-dev/teams","hooks_url":"https://api.github.com/repos/akeneo/pim-community-dev/hooks","issue_events_url":"https://api.github.com/repos/akeneo/pim-community-dev/issues/events{/number}","events_url":"https://api.github.com/repos/akeneo/pim-community-dev/events","assignees_url":"https://api.github.com/repos/akeneo/pim-community-dev/assignees{/user}","branches_url":"https://api.github.com/repos/akeneo/pim-community-dev/branches{/branch}","tags_url":"https://api.github.com/repos/akeneo/pim-community-dev/tags","blobs_url":"https://api.github.com/repos/akeneo/pim-community-dev/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/akeneo/pim-community-dev/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/akeneo/pim-community-dev/git/refs{/sha}","trees_url":"https://api.github.com/repos/akeneo/pim-community-dev/git/trees{/sha}","statuses_url":"https://api.github.com/repos/akeneo/pim-community-dev/statuses/{sha}","languages_url":"https://api.github.com/repos/akeneo/pim-community-dev/languages","stargazers_url":"https://api.github.com/repos/akeneo/pim-community-dev/stargazers","contributors_url":"https://api.github.com/repos/akeneo/pim-community-dev/contributors","subscribers_url":"https://api.github.com/repos/akeneo/pim-community-dev/subscribers","subscription_url":"https://api.github.com/repos/akeneo/pim-community-dev/subscription","commits_url":"https://api.github.com/repos/akeneo/pim-community-dev/commits{/sha}","git_commits_url":"https://api.github.com/repos/akeneo/pim-community-dev/git/commits{/sha}","comments_url":"https://api.github.com/repos/akeneo/pim-community-dev/comments{/number}","issue_comment_url":"https://api.github.com/repos/akeneo/pim-community-dev/issues/comments{/number}","contents_url":"https://api.github.com/repos/akeneo/pim-community-dev/contents/{+path}","compare_url":"https://api.github.com/repos/akeneo/pim-community-dev/compare/{base}...{head}","merges_url":"https://api.github.com/repos/akeneo/pim-community-dev/merges","archive_url":"https://api.github.com/repos/akeneo/pim-community-dev/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/akeneo/pim-community-dev/downloads","issues_url":"https://api.github.com/repos/akeneo/pim-community-dev/issues{/number}","pulls_url":"https://api.github.com/repos/akeneo/pim-community-dev/pulls{/number}","milestones_url":"https://api.github.com/repos/akeneo/pim-community-dev/milestones{/number}","notifications_url":"https://api.github.com/repos/akeneo/pim-community-dev/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/akeneo/pim-community-dev/labels{/name}","releases_url":"https://api.github.com/repos/akeneo/pim-community-dev/releases{/id}","deployments_url":"https://api.github.com/repos/akeneo/pim-community-dev/deployments","created_at":"2012-08-10T09:27:26Z","updated_at":"2016-04-14T14:29:57Z","pushed_at":"2016-04-20T15:43:47Z","git_url":"git://github.com/akeneo/pim-community-dev.git","ssh_url":"git@github.com:akeneo/pim-community-dev.git","clone_url":"https://github.com/akeneo/pim-community-dev.git","svn_url":"https://github.com/akeneo/pim-community-dev","homepage":"http://www.akeneo.com","size":140405,"stargazers_count":304,"watchers_count":304,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":158,"mirror_url":null,"open_issues_count":99,"forks":158,"open_issues":99,"watchers":304,"default_branch":"master"}},"base":{"label":"akeneo:master","ref":"master","sha":"3f147d1270f39b11c20fbf8ed0905435d6391f8b","user":{"login":"akeneo","id":2510186,"avatar_url":"https://avatars.githubusercontent.com/u/2510186?v=3","gravatar_id":"","url":"https://api.github.com/users/akeneo","html_url":"https://github.com/akeneo","followers_url":"https://api.github.com/users/akeneo/followers","following_url":"https://api.github.com/users/akeneo/following{/other_user}","gists_url":"https://api.github.com/users/akeneo/gists{/gist_id}","starred_url":"https://api.github.com/users/akeneo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akeneo/subscriptions","organizations_url":"https://api.github.com/users/akeneo/orgs","repos_url":"https://api.github.com/users/akeneo/repos","events_url":"https://api.github.com/users/akeneo/events{/privacy}","received_events_url":"https://api.github.com/users/akeneo/received_events","type":"Organization","site_admin":false},"repo":{"id":5367323,"name":"pim-community-dev","full_name":"akeneo/pim-community-dev","owner":{"login":"akeneo","id":2510186,"avatar_url":"https://avatars.githubusercontent.com/u/2510186?v=3","gravatar_id":"","url":"https://api.github.com/users/akeneo","html_url":"https://github.com/akeneo","followers_url":"https://api.github.com/users/akeneo/followers","following_url":"https://api.github.com/users/akeneo/following{/other_user}","gists_url":"https://api.github.com/users/akeneo/gists{/gist_id}","starred_url":"https://api.github.com/users/akeneo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/akeneo/subscriptions","organizations_url":"https://api.github.com/users/akeneo/orgs","repos_url":"https://api.github.com/users/akeneo/repos","events_url":"https://api.github.com/users/akeneo/events{/privacy}","received_events_url":"https://api.github.com/users/akeneo/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/akeneo/pim-community-dev","description":"[Community Development Repository] The open source Product Information Management (PIM)","fork":false,"url":"https://api.github.com/repos/akeneo/pim-community-dev","forks_url":"https://api.github.com/repos/akeneo/pim-community-dev/forks","keys_url":"https://api.github.com/repos/akeneo/pim-community-dev/keys{/key_id}","collaborators_url":"https://api.github.com/repos/akeneo/pim-community-dev/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/akeneo/pim-community-dev/teams","hooks_url":"https://api.github.com/repos/akeneo/pim-community-dev/hooks","issue_events_url":"https://api.github.com/repos/akeneo/pim-community-dev/issues/events{/number}","events_url":"https://api.github.com/repos/akeneo/pim-community-dev/events","assignees_url":"https://api.github.com/repos/akeneo/pim-community-dev/assignees{/user}","branches_url":"https://api.github.com/repos/akeneo/pim-community-dev/branches{/branch}","tags_url":"https://api.github.com/repos/akeneo/pim-community-dev/tags","blobs_url":"https://api.github.com/repos/akeneo/pim-community-dev/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/akeneo/pim-community-dev/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/akeneo/pim-community-dev/git/refs{/sha}","trees_url":"https://api.github.com/repos/akeneo/pim-community-dev/git/trees{/sha}","statuses_url":"https://api.github.com/repos/akeneo/pim-community-dev/statuses/{sha}","languages_url":"https://api.github.com/repos/akeneo/pim-community-dev/languages","stargazers_url":"https://api.github.com/repos/akeneo/pim-community-dev/stargazers","contributors_url":"https://api.github.com/repos/akeneo/pim-community-dev/contributors","subscribers_url":"https://api.github.com/repos/akeneo/pim-community-dev/subscribers","subscription_url":"https://api.github.com/repos/akeneo/pim-community-dev/subscription","commits_url":"https://api.github.com/repos/akeneo/pim-community-dev/commits{/sha}","git_commits_url":"https://api.github.com/repos/akeneo/pim-community-dev/git/commits{/sha}","comments_url":"https://api.github.com/repos/akeneo/pim-community-dev/comments{/number}","issue_comment_url":"https://api.github.com/repos/akeneo/pim-community-dev/issues/comments{/number}","contents_url":"https://api.github.com/repos/akeneo/pim-community-dev/contents/{+path}","compare_url":"https://api.github.com/repos/akeneo/pim-community-dev/compare/{base}...{head}","merges_url":"https://api.github.com/repos/akeneo/pim-community-dev/merges","archive_url":"https://api.github.com/repos/akeneo/pim-community-dev/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/akeneo/pim-community-dev/downloads","issues_url":"https://api.github.com/repos/akeneo/pim-community-dev/issues{/number}","pulls_url":"https://api.github.com/repos/akeneo/pim-community-dev/pulls{/number}","milestones_url":"https://api.github.com/repos/akeneo/pim-community-dev/milestones{/number}","notifications_url":"https://api.github.com/repos/akeneo/pim-community-dev/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/akeneo/pim-community-dev/labels{/name}","releases_url":"https://api.github.com/repos/akeneo/pim-community-dev/releases{/id}","deployments_url":"https://api.github.com/repos/akeneo/pim-community-dev/deployments","created_at":"2012-08-10T09:27:26Z","updated_at":"2016-04-14T14:29:57Z","pushed_at":"2016-04-20T15:43:47Z","git_url":"git://github.com/akeneo/pim-community-dev.git","ssh_url":"git@github.com:akeneo/pim-community-dev.git","clone_url":"https://github.com/akeneo/pim-community-dev.git","svn_url":"https://github.com/akeneo/pim-community-dev","homepage":"http://www.akeneo.com","size":140405,"stargazers_count":304,"watchers_count":304,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":158,"mirror_url":null,"open_issues_count":99,"forks":158,"open_issues":99,"watchers":304,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/4285"},"html":{"href":"https://github.com/akeneo/pim-community-dev/pull/4285"},"issue":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/issues/4285"},"comments":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/issues/4285/comments"},"review_comments":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/4285/comments"},"review_comment":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/4285/commits"},"statuses":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/statuses/09b37caaaeb311cf005e606cd21fa60306cbbbfc"}}}}