{"action":"created","comment":{"url":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/comments/57933448","id":57933448,"diff_hunk":"@@ -0,0 +1,288 @@\n+<?php\n+\n+namespace Pim\\Component\\Connector\\Reader\\File;\n+\n+use Akeneo\\Component\\Batch\\Item\\InvalidItemException;\n+use Box\\Spout\\Common\\Type;\n+use Box\\Spout\\Reader\\IteratorInterface;\n+use Box\\Spout\\Reader\\ReaderFactory;\n+use Box\\Spout\\Reader\\ReaderInterface;\n+use Pim\\Component\\Connector\\Exception\\FileIteratorException;\n+use Symfony\\Component\\Filesystem\\Exception\\FileNotFoundException;\n+use Symfony\\Component\\Filesystem\\Filesystem;\n+use Symfony\\Component\\Finder\\Finder;\n+\n+/**\n+ * File iterator\n+ *\n+ * @author    Marie Bochu <marie.bochu@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 FileIterator implements FileIteratorInterface\n+{\n+    /** @var string */\n+    protected $type;\n+\n+    /** @var ReaderInterface */\n+    protected $reader;\n+\n+    /** @var string */\n+    protected $filePath;\n+\n+    /** @var \\SplFileInfo */\n+    protected $fileInfo;\n+\n+    /** @var string */\n+    protected $archivePath;\n+\n+    /** @var IteratorInterface */\n+    protected $rows;\n+\n+    /** @var array */\n+    protected $headers;\n+\n+    /**\n+     * @param string $type\n+     */\n+    public function __construct($type)\n+    {\n+        $this->type   = $type;\n+        $this->reader = ReaderFactory::create($type);\n+    }\n+\n+    /**\n+     * {@inheritdoc}\n+     *\n+     * @throws FileNotFoundException\n+     */\n+    public function rewind()\n+    {\n+        if (!$this->fileInfo->isFile()) {\n+            throw new FileNotFoundException(sprintf('File \"%s\" could not be found', $this->filePath));\n+        }\n+\n+        $mimeType = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $this->filePath);\n+        if ('application/zip' === $mimeType && Type::XLSX !== $this->fileInfo->getExtension()) {\n+            $this->extractZipArchive();\n+        }\n+\n+        $this->reader->open($this->filePath);\n+        $this->reader->getSheetIterator()->rewind();\n+        $sheet = $this->reader->getSheetIterator()->current();\n+        $sheet->getRowIterator()->rewind();\n+\n+        $this->headers = $sheet->getRowIterator()->current();\n+        $this->rows    = $sheet->getRowIterator();\n+    }\n+\n+    /**\n+     * {@inheritdoc}\n+     *\n+     * @throws FileIteratorException\n+     * @throws InvalidItemException\n+     */\n+    public function current()\n+    {\n+        if (null === $this->rows) {\n+            throw new FileIteratorException();\n+        }\n+\n+        $data = $this->rows->current();\n+\n+        if (!$this->valid() || null === $data || empty($data)) {\n+            $this->reset();\n+\n+            return null;\n+        }\n+\n+        $countHeaders = count($this->headers);\n+        $countData    = count($data);\n+\n+        if ($countHeaders < $countData) {\n+            throw new InvalidItemException(\n+                'pim_connector.steps.file_reader.invalid_item_columns_count',\n+                $data,\n+                [\n+                    '%totalColumnsCount%' => $countHeaders,\n+                    '%itemColumnsCount%'  => $countData,\n+                    '%filePath%'          => $this->filePath,\n+                    '%lineno%'            => $this->rows->key()\n+                ]\n+            );\n+        }\n+\n+        if ($countHeaders > $countData) {\n+            $missingValuesCount = $countHeaders - $countData;\n+            $missingValues = array_fill(0, $missingValuesCount, '');\n+            $data = array_merge($data, $missingValues);\n+        }\n+\n+        $data = array_combine($this->headers, $data);\n+\n+        return $data;\n+    }\n+\n+    /**\n+     * {@inheritdoc}\n+     *\n+     * @throws FileIteratorException\n+     */\n+    public function next()\n+    {\n+        if (null === $this->rows) {\n+            throw new FileIteratorException();\n+        }\n+\n+        $this->rows->next();\n+    }\n+\n+    /**\n+     * {@inheritdoc}\n+     *\n+     * @throws FileIteratorException\n+     */\n+    public function key()\n+    {\n+        if (null === $this->rows) {\n+            throw new FileIteratorException();\n+        }\n+\n+        return $this->rows->key();\n+    }\n+\n+    /**\n+     * {@inheritdoc}\n+     *\n+     * @throws FileIteratorException\n+     */\n+    public function valid()\n+    {\n+        if (null === $this->rows) {\n+            throw new FileIteratorException();\n+        }\n+\n+        return $this->rows->valid();\n+    }\n+\n+    /**\n+     * {@inheritdoc}\n+     */\n+    public function isInitialized()\n+    {\n+        return null !== $this->rows;\n+    }\n+\n+    /**\n+     * {@inheritdoc}\n+     */\n+    public function reset()\n+    {\n+        $this->reader->close();\n+\n+        $this->rows     = null;\n+        $this->headers  = null;\n+        $this->fileInfo = null;\n+        $this->filePath = null;\n+    }\n+\n+    /**\n+     * {@inheritdoc}\n+     *\n+     * @throws \\LogicException\n+     */\n+    public function setReaderOptions(array $options = [])\n+    {\n+        foreach ($options as $name => $option) {\n+            $setter = 'set' . ucfirst($name);\n+            if (method_exists($this->reader, $setter)) {\n+                $this->reader->$setter($option);\n+            } else {\n+                $message = sprintf('Option \"%s\" does not exist in reader \"%s\"', $setter, get_class($this->reader));\n+                throw new \\LogicException($message);\n+            }\n+        }\n+\n+        return $this;\n+    }\n+\n+    /**\n+     * {@inheritdoc}\n+     */\n+    public function setFilePath($filePath)","path":"src/Pim/Component/Connector/Reader/File/FileIterator.php","position":212,"original_position":212,"commit_id":"ced0999650da514b226a694ea727d05937eb177a","original_commit_id":"ced0999650da514b226a694ea727d05937eb177a","user":{"login":"phaseinducer","id":659491,"avatar_url":"https://avatars.githubusercontent.com/u/659491?v=3","gravatar_id":"","url":"https://api.github.com/users/phaseinducer","html_url":"https://github.com/phaseinducer","followers_url":"https://api.github.com/users/phaseinducer/followers","following_url":"https://api.github.com/users/phaseinducer/following{/other_user}","gists_url":"https://api.github.com/users/phaseinducer/gists{/gist_id}","starred_url":"https://api.github.com/users/phaseinducer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/phaseinducer/subscriptions","organizations_url":"https://api.github.com/users/phaseinducer/orgs","repos_url":"https://api.github.com/users/phaseinducer/repos","events_url":"https://api.github.com/users/phaseinducer/events{/privacy}","received_events_url":"https://api.github.com/users/phaseinducer/received_events","type":"User","site_admin":false},"body":"This has two withdrawals : it creates a dependency between the methods, and if your iterator is injected in two other services it will share the same file.\r\n\r\nA file iterator makes no sense without a file to manipulate, so it should be passed to the constructor. The iterator should not be a service but instantiated by a factory and the file path would be a mandatory param of the factory.\r\nPlus using a factory will guaranty that you will never share an instance of an iterator between services.","created_at":"2016-03-30T17:56:02Z","updated_at":"2016-03-30T17:56:02Z","html_url":"https://github.com/akeneo/pim-community-dev/pull/4131#discussion_r57933448","pull_request_url":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/4131","_links":{"self":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/comments/57933448"},"html":{"href":"https://github.com/akeneo/pim-community-dev/pull/4131#discussion_r57933448"},"pull_request":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/4131"}}},"pull_request":{"url":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/4131","id":62370019,"html_url":"https://github.com/akeneo/pim-community-dev/pull/4131","diff_url":"https://github.com/akeneo/pim-community-dev/pull/4131.diff","patch_url":"https://github.com/akeneo/pim-community-dev/pull/4131.patch","issue_url":"https://api.github.com/repos/akeneo/pim-community-dev/issues/4131","number":4131,"state":"open","locked":false,"title":"PIM-5093: import products with XLSX files","user":{"login":"skeleton","id":1131230,"avatar_url":"https://avatars.githubusercontent.com/u/1131230?v=3","gravatar_id":"","url":"https://api.github.com/users/skeleton","html_url":"https://github.com/skeleton","followers_url":"https://api.github.com/users/skeleton/followers","following_url":"https://api.github.com/users/skeleton/following{/other_user}","gists_url":"https://api.github.com/users/skeleton/gists{/gist_id}","starred_url":"https://api.github.com/users/skeleton/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/skeleton/subscriptions","organizations_url":"https://api.github.com/users/skeleton/orgs","repos_url":"https://api.github.com/users/skeleton/repos","events_url":"https://api.github.com/users/skeleton/events{/privacy}","received_events_url":"https://api.github.com/users/skeleton/received_events","type":"User","site_admin":false},"body":"```\r\n| Q                                 | A\r\n| --------------------------------- | ---\r\n| Added Specs                       | Y\r\n| Added Behats                      | Y\r\n| Changelog updated                 | N\r\n| Micro Demo to the PO (Story only) | Y\r\n| Migration script                  | N\r\n| Tech Doc                          | N\r\n```\r\n","created_at":"2016-03-10T10:42:02Z","updated_at":"2016-03-30T17:56:02Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7541a706da29b3c7147d9177c02f0a0070cb6222","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/4131/commits","review_comments_url":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/4131/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/4131/comments","statuses_url":"https://api.github.com/repos/akeneo/pim-community-dev/statuses/ced0999650da514b226a694ea727d05937eb177a","head":{"label":"akeneo:PIM-5093","ref":"PIM-5093","sha":"ced0999650da514b226a694ea727d05937eb177a","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-03-26T19:45:00Z","pushed_at":"2016-03-30T16:33:57Z","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":139356,"stargazers_count":297,"watchers_count":297,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":158,"mirror_url":null,"open_issues_count":117,"forks":158,"open_issues":117,"watchers":297,"default_branch":"master"}},"base":{"label":"akeneo:master","ref":"master","sha":"8e72be14f65850b168ba6c37d518d80a3bc84bb0","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-03-26T19:45:00Z","pushed_at":"2016-03-30T16:33:57Z","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":139356,"stargazers_count":297,"watchers_count":297,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":158,"mirror_url":null,"open_issues_count":117,"forks":158,"open_issues":117,"watchers":297,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/4131"},"html":{"href":"https://github.com/akeneo/pim-community-dev/pull/4131"},"issue":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/issues/4131"},"comments":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/issues/4131/comments"},"review_comments":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/pulls/4131/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/4131/commits"},"statuses":{"href":"https://api.github.com/repos/akeneo/pim-community-dev/statuses/ced0999650da514b226a694ea727d05937eb177a"}}}}