{"action":"created","comment":{"url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/pulls/comments/25674104","id":25674104,"diff_hunk":"@@ -0,0 +1,125 @@\n+<?php\n+/*\n+ * This file is part of the Sulu CMS.\n+ *\n+ * (c) MASSIVE ART WebServices GmbH\n+ *\n+ * This source file is subject to the MIT license that is bundled\n+ * with this source code in the file LICENSE.\n+ */\n+\n+namespace Massive\\Bundle\\SearchBundle\\Search\\Metadata;\n+\n+use Symfony\\Component\\ExpressionLanguage\\ExpressionLanguage;\n+use Symfony\\Component\\PropertyAccess\\PropertyAccess;\n+use Massive\\Bundle\\SearchBundle\\Search\\Metadata\\Field\\Property;\n+use Massive\\Bundle\\SearchBundle\\Search\\Metadata\\Field\\Field;\n+use Massive\\Bundle\\SearchBundle\\Search\\Metadata\\Field\\Expression;\n+\n+/**\n+ * Evaluate the value of fields\n+ */\n+class FieldEvaluator\n+{\n+    /**\n+     * @var ExpressionLanguage\n+     */\n+    private $expressionLanguage;\n+\n+    /**\n+     * @var PropertyAccess\n+     */\n+    private $accessor;\n+\n+    /**\n+     * @param Factory $factory\n+     * @param ExpressionLanguage $expressionLanguage\n+     */\n+    public function __construct(ExpressionLanguage $expressionLanguage)\n+    {\n+        $this->expressionLanguage = $expressionLanguage;\n+        $this->accessor = PropertyAccess::createPropertyAccessor();\n+    }\n+\n+    /**\n+     * Evaluate the value from the given object and field\n+     *\n+     * @param mixed $object\n+     * @param mixed $field\n+     */\n+    public function getValue($object, FieldInterface $field)\n+    {\n+        try {\n+            switch (get_class($field)) {\n+                case 'Massive\\Bundle\\SearchBundle\\Search\\Metadata\\Field\\Property':\n+                    return $this->getPropertyValue($object, $field);\n+                case 'Massive\\Bundle\\SearchBundle\\Search\\Metadata\\Field\\Expression':\n+                    return $this->getExpressionValue($object, $field);\n+                case 'Massive\\Bundle\\SearchBundle\\Search\\Metadata\\Field\\Field':\n+                    return $this->getFieldValue($object, $field);\n+            }\n+        } catch (\\Exception $e) {\n+            throw new \\Exception(sprintf(\n+                'Error encountered when trying to determine value from object \"%s\"',\n+                get_class($object)\n+            ), null, $e);\n+        }\n+\n+        throw new \\RuntimeException(sprintf(\n+            'Unknown field type \"%s\" when trying to convert \"%s\" into a search document',\n+            get_class($field),\n+            get_class($object)\n+        ));\n+    }\n+\n+    /**\n+     * Evaluate a property (using PropertyAccess)\n+     *\n+     * @param mixed $object\n+     * @param Property $field\n+     */\n+    private function getPropertyValue($object, Property $field)\n+    {\n+        return $this->accessor->getValue($object, $field->getProperty());\n+    }\n+\n+    /**\n+     * Return a value determined from the name of the field\n+     * rather than an explicit property.\n+     *\n+     * If the object is an array, then force the array syntax.\n+     *\n+     * @param mixed $object\n+     * @param Field $field\n+     */\n+    private function getFieldValue($object, Field $field)\n+    {\n+        if (is_array($object)) {\n+            $path = '[' . $field->getName(). ']';\n+        } else {\n+            $path = $field->getName();\n+        }\n+\n+        return $this->accessor->getValue($object, $path);\n+    }\n+\n+    /**\n+     * Evaluate an expression (ExpressionLanguage)\n+     *\n+     * @param mixed $object\n+     * @param Expression $field\n+     */\n+    private function getExpressionValue($object, Expression $field)\n+    {\n+        try {\n+            return $this->expressionLanguage->evaluate($field->getExpression(), array(\n+                'object' => $object,\n+            ));\n+        } catch (\\Exception $e) {\n+            throw new \\RuntimeException(sprintf(\n+                'Error encountered when evaluating expression \"%s\"',\n+                $field->getExpression()\n+            ), null, $e);\n+        }\n+    }\n+}","path":"Search/Metadata/FieldEvaluator.php","position":125,"original_position":125,"commit_id":"773d691f879b66c0388469418f947ba060ba99f6","original_commit_id":"773d691f879b66c0388469418f947ba060ba99f6","user":{"login":"dantleech","id":530801,"avatar_url":"https://avatars.githubusercontent.com/u/530801?v=3","gravatar_id":"","url":"https://api.github.com/users/dantleech","html_url":"https://github.com/dantleech","followers_url":"https://api.github.com/users/dantleech/followers","following_url":"https://api.github.com/users/dantleech/following{/other_user}","gists_url":"https://api.github.com/users/dantleech/gists{/gist_id}","starred_url":"https://api.github.com/users/dantleech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dantleech/subscriptions","organizations_url":"https://api.github.com/users/dantleech/orgs","repos_url":"https://api.github.com/users/dantleech/repos","events_url":"https://api.github.com/users/dantleech/events{/privacy}","received_events_url":"https://api.github.com/users/dantleech/received_events","type":"User","site_admin":false},"body":"ExpressionLanguage could throw a number of Exceptions. I wrap any exception that it does throw. I think that is fine.","created_at":"2015-03-03T09:49:13Z","updated_at":"2015-03-03T09:49:13Z","html_url":"https://github.com/massiveart/MassiveSearchBundle/pull/18#discussion_r25674104","pull_request_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/pulls/18","_links":{"self":{"href":"https://api.github.com/repos/massiveart/MassiveSearchBundle/pulls/comments/25674104"},"html":{"href":"https://github.com/massiveart/MassiveSearchBundle/pull/18#discussion_r25674104"},"pull_request":{"href":"https://api.github.com/repos/massiveart/MassiveSearchBundle/pulls/18"}}},"pull_request":{"url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/pulls/18","id":28102164,"html_url":"https://github.com/massiveart/MassiveSearchBundle/pull/18","diff_url":"https://github.com/massiveart/MassiveSearchBundle/pull/18.diff","patch_url":"https://github.com/massiveart/MassiveSearchBundle/pull/18.patch","issue_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/issues/18","number":18,"state":"open","locked":false,"title":"Feature/rest api","user":{"login":"dantleech","id":530801,"avatar_url":"https://avatars.githubusercontent.com/u/530801?v=3","gravatar_id":"","url":"https://api.github.com/users/dantleech","html_url":"https://github.com/dantleech","followers_url":"https://api.github.com/users/dantleech/followers","following_url":"https://api.github.com/users/dantleech/following{/other_user}","gists_url":"https://api.github.com/users/dantleech/gists{/gist_id}","starred_url":"https://api.github.com/users/dantleech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dantleech/subscriptions","organizations_url":"https://api.github.com/users/dantleech/orgs","repos_url":"https://api.github.com/users/dantleech/repos","events_url":"https://api.github.com/users/dantleech/events{/privacy}","received_events_url":"https://api.github.com/users/dantleech/received_events","type":"User","site_admin":false},"body":"This PR adds a Doctrine ORM subscriber, REST API and ExpressionLanaugage and *numerous other* features facilitating the creation of an independent back office search.\r\n\r\n- Added Doctrine ORM subscriber will automatically index/deindex mapped ORM documents.\r\n- `massive:search:index:rebuild` command which rebuilds both the ORM and third-party (i.e. Sulu) implementations)\r\n- Introduction of a REST API to provide a simple controller to perform a search query using parameters `query`, `index` and `locale` and receieve a JSON response.\r\n- Introduction of multiple search *contexts* for each mapped object, possiblity to index things differently for back or front office searches.\r\n- Added behat tests\r\n\r\nTodo\r\n\r\n- [x] API to retrieve valid indexes (or maybe that should be defined elsewhere?)\r\n- [x] ORM subscriber DI Configuration + tag\r\n- [x] Expression language support (for generating URLs)\r\n- [x] Context support (in the mapping)\r\n\r\n- Docs in separate PR: https://github.com/massiveart/MassiveSearchBundle/pull/20","created_at":"2015-01-27T11:44:40Z","updated_at":"2015-03-03T09:49:13Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0f1f9ade85060fedfdd9bc046aa10984dc2bf8c4","assignee":{"login":"dantleech","id":530801,"avatar_url":"https://avatars.githubusercontent.com/u/530801?v=3","gravatar_id":"","url":"https://api.github.com/users/dantleech","html_url":"https://github.com/dantleech","followers_url":"https://api.github.com/users/dantleech/followers","following_url":"https://api.github.com/users/dantleech/following{/other_user}","gists_url":"https://api.github.com/users/dantleech/gists{/gist_id}","starred_url":"https://api.github.com/users/dantleech/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dantleech/subscriptions","organizations_url":"https://api.github.com/users/dantleech/orgs","repos_url":"https://api.github.com/users/dantleech/repos","events_url":"https://api.github.com/users/dantleech/events{/privacy}","received_events_url":"https://api.github.com/users/dantleech/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/pulls/18/commits","review_comments_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/pulls/18/comments","review_comment_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/pulls/comments{/number}","comments_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/issues/18/comments","statuses_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/statuses/773d691f879b66c0388469418f947ba060ba99f6","head":{"label":"massiveart:feature/rest-api","ref":"feature/rest-api","sha":"773d691f879b66c0388469418f947ba060ba99f6","user":{"login":"massiveart","id":854731,"avatar_url":"https://avatars.githubusercontent.com/u/854731?v=3","gravatar_id":"","url":"https://api.github.com/users/massiveart","html_url":"https://github.com/massiveart","followers_url":"https://api.github.com/users/massiveart/followers","following_url":"https://api.github.com/users/massiveart/following{/other_user}","gists_url":"https://api.github.com/users/massiveart/gists{/gist_id}","starred_url":"https://api.github.com/users/massiveart/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/massiveart/subscriptions","organizations_url":"https://api.github.com/users/massiveart/orgs","repos_url":"https://api.github.com/users/massiveart/repos","events_url":"https://api.github.com/users/massiveart/events{/privacy}","received_events_url":"https://api.github.com/users/massiveart/received_events","type":"Organization","site_admin":false},"repo":{"id":23216604,"name":"MassiveSearchBundle","full_name":"massiveart/MassiveSearchBundle","owner":{"login":"massiveart","id":854731,"avatar_url":"https://avatars.githubusercontent.com/u/854731?v=3","gravatar_id":"","url":"https://api.github.com/users/massiveart","html_url":"https://github.com/massiveart","followers_url":"https://api.github.com/users/massiveart/followers","following_url":"https://api.github.com/users/massiveart/following{/other_user}","gists_url":"https://api.github.com/users/massiveart/gists{/gist_id}","starred_url":"https://api.github.com/users/massiveart/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/massiveart/subscriptions","organizations_url":"https://api.github.com/users/massiveart/orgs","repos_url":"https://api.github.com/users/massiveart/repos","events_url":"https://api.github.com/users/massiveart/events{/privacy}","received_events_url":"https://api.github.com/users/massiveart/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/massiveart/MassiveSearchBundle","description":"","fork":false,"url":"https://api.github.com/repos/massiveart/MassiveSearchBundle","forks_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/forks","keys_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/keys{/key_id}","collaborators_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/teams","hooks_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/hooks","issue_events_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/issues/events{/number}","events_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/events","assignees_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/assignees{/user}","branches_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/branches{/branch}","tags_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/tags","blobs_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/git/refs{/sha}","trees_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/git/trees{/sha}","statuses_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/statuses/{sha}","languages_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/languages","stargazers_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/stargazers","contributors_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/contributors","subscribers_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/subscribers","subscription_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/subscription","commits_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/commits{/sha}","git_commits_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/git/commits{/sha}","comments_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/comments{/number}","issue_comment_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/issues/comments{/number}","contents_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/contents/{+path}","compare_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/compare/{base}...{head}","merges_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/merges","archive_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/downloads","issues_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/issues{/number}","pulls_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/pulls{/number}","milestones_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/milestones{/number}","notifications_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/labels{/name}","releases_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/releases{/id}","created_at":"2014-08-22T07:19:25Z","updated_at":"2015-02-06T10:21:45Z","pushed_at":"2015-03-02T09:34:01Z","git_url":"git://github.com/massiveart/MassiveSearchBundle.git","ssh_url":"git@github.com:massiveart/MassiveSearchBundle.git","clone_url":"https://github.com/massiveart/MassiveSearchBundle.git","svn_url":"https://github.com/massiveart/MassiveSearchBundle","homepage":null,"size":1084,"stargazers_count":1,"watchers_count":1,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":8,"forks":0,"open_issues":8,"watchers":1,"default_branch":"develop"}},"base":{"label":"massiveart:develop","ref":"develop","sha":"8023d43e1eb6d0df34d300bf909d9c37b8500c3c","user":{"login":"massiveart","id":854731,"avatar_url":"https://avatars.githubusercontent.com/u/854731?v=3","gravatar_id":"","url":"https://api.github.com/users/massiveart","html_url":"https://github.com/massiveart","followers_url":"https://api.github.com/users/massiveart/followers","following_url":"https://api.github.com/users/massiveart/following{/other_user}","gists_url":"https://api.github.com/users/massiveart/gists{/gist_id}","starred_url":"https://api.github.com/users/massiveart/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/massiveart/subscriptions","organizations_url":"https://api.github.com/users/massiveart/orgs","repos_url":"https://api.github.com/users/massiveart/repos","events_url":"https://api.github.com/users/massiveart/events{/privacy}","received_events_url":"https://api.github.com/users/massiveart/received_events","type":"Organization","site_admin":false},"repo":{"id":23216604,"name":"MassiveSearchBundle","full_name":"massiveart/MassiveSearchBundle","owner":{"login":"massiveart","id":854731,"avatar_url":"https://avatars.githubusercontent.com/u/854731?v=3","gravatar_id":"","url":"https://api.github.com/users/massiveart","html_url":"https://github.com/massiveart","followers_url":"https://api.github.com/users/massiveart/followers","following_url":"https://api.github.com/users/massiveart/following{/other_user}","gists_url":"https://api.github.com/users/massiveart/gists{/gist_id}","starred_url":"https://api.github.com/users/massiveart/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/massiveart/subscriptions","organizations_url":"https://api.github.com/users/massiveart/orgs","repos_url":"https://api.github.com/users/massiveart/repos","events_url":"https://api.github.com/users/massiveart/events{/privacy}","received_events_url":"https://api.github.com/users/massiveart/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/massiveart/MassiveSearchBundle","description":"","fork":false,"url":"https://api.github.com/repos/massiveart/MassiveSearchBundle","forks_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/forks","keys_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/keys{/key_id}","collaborators_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/teams","hooks_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/hooks","issue_events_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/issues/events{/number}","events_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/events","assignees_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/assignees{/user}","branches_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/branches{/branch}","tags_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/tags","blobs_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/git/refs{/sha}","trees_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/git/trees{/sha}","statuses_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/statuses/{sha}","languages_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/languages","stargazers_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/stargazers","contributors_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/contributors","subscribers_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/subscribers","subscription_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/subscription","commits_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/commits{/sha}","git_commits_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/git/commits{/sha}","comments_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/comments{/number}","issue_comment_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/issues/comments{/number}","contents_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/contents/{+path}","compare_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/compare/{base}...{head}","merges_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/merges","archive_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/downloads","issues_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/issues{/number}","pulls_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/pulls{/number}","milestones_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/milestones{/number}","notifications_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/labels{/name}","releases_url":"https://api.github.com/repos/massiveart/MassiveSearchBundle/releases{/id}","created_at":"2014-08-22T07:19:25Z","updated_at":"2015-02-06T10:21:45Z","pushed_at":"2015-03-02T09:34:01Z","git_url":"git://github.com/massiveart/MassiveSearchBundle.git","ssh_url":"git@github.com:massiveart/MassiveSearchBundle.git","clone_url":"https://github.com/massiveart/MassiveSearchBundle.git","svn_url":"https://github.com/massiveart/MassiveSearchBundle","homepage":null,"size":1084,"stargazers_count":1,"watchers_count":1,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":8,"forks":0,"open_issues":8,"watchers":1,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/massiveart/MassiveSearchBundle/pulls/18"},"html":{"href":"https://github.com/massiveart/MassiveSearchBundle/pull/18"},"issue":{"href":"https://api.github.com/repos/massiveart/MassiveSearchBundle/issues/18"},"comments":{"href":"https://api.github.com/repos/massiveart/MassiveSearchBundle/issues/18/comments"},"review_comments":{"href":"https://api.github.com/repos/massiveart/MassiveSearchBundle/pulls/18/comments"},"review_comment":{"href":"https://api.github.com/repos/massiveart/MassiveSearchBundle/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/massiveart/MassiveSearchBundle/pulls/18/commits"},"statuses":{"href":"https://api.github.com/repos/massiveart/MassiveSearchBundle/statuses/773d691f879b66c0388469418f947ba060ba99f6"}}}}