{"action":"opened","number":2,"pull_request":{"url":"https://api.github.com/repos/chomb94/foundry/pulls/2","id":48658742,"html_url":"https://github.com/chomb94/foundry/pull/2","diff_url":"https://github.com/chomb94/foundry/pull/2.diff","patch_url":"https://github.com/chomb94/foundry/pull/2.patch","issue_url":"https://api.github.com/repos/chomb94/foundry/issues/2","number":2,"state":"open","locked":false,"title":"Tech review & cleanup","user":{"login":"ninsuo","id":4152132,"avatar_url":"https://avatars.githubusercontent.com/u/4152132?v=3","gravatar_id":"","url":"https://api.github.com/users/ninsuo","html_url":"https://github.com/ninsuo","followers_url":"https://api.github.com/users/ninsuo/followers","following_url":"https://api.github.com/users/ninsuo/following{/other_user}","gists_url":"https://api.github.com/users/ninsuo/gists{/gist_id}","starred_url":"https://api.github.com/users/ninsuo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ninsuo/subscriptions","organizations_url":"https://api.github.com/users/ninsuo/orgs","repos_url":"https://api.github.com/users/ninsuo/repos","events_url":"https://api.github.com/users/ninsuo/events{/privacy}","received_events_url":"https://api.github.com/users/ninsuo/received_events","type":"User","site_admin":false},"body":"\r\n1) refactoring\r\n\r\na) added a complete gitignore for symfony\r\n=> based on https://github.com/github/gitignore/blob/master/Symfony.gitignore the problem with a non-full gitignore\r\nis that collective maintenance will conflict more on useless/generated files.\r\n\r\nb) about parameters.yml\r\n=> you should edit parameters.yml.dist when you need to add new parameters, and then\r\nrun composer update (or composer install, as you wish) to generate it again and get\r\nprompted to fill out the new keys. This let you put sensitive info inside parameters.yml\r\nand push only the parameters.yml.dist (for example, google credentials should not be public)\r\n\r\nc) about controllers\r\n=> views are stored in the bundle, we use app/ only to overwrite third-party views\r\n=> do not hesitate to abuse of using annotations, @Route, but also @Template and @Security. For example:\r\n\r\n```php\r\nclass AdminController extends Controller\r\n{\r\n    /**\r\n     * @Route(\"/admin\", name=\"admin\")\r\n     * @Security(\"has_role('ROLE_ADMIN')\")\r\n     * @Template()\r\n     */\r\n    public function indexAction()\r\n    {\r\n        return array();\r\n    }\r\n}\r\n```\r\n\r\nHere,\r\n- {{ path('admin') }} will generate /admin link who'll point to AdminController:adminAction\r\n- Only users possessing ROLE_ADMIN role will be able to access it (else a login page or a 403 is fired)\r\n- The Admin/index.html.twig will be used as template (because [Admin]Controller and [index]Action)\r\n\r\n=> also note that all controller methods always finish by *Action:\r\n\r\n```php\r\npublic function projectEdit(Request $request, $id)\r\npublic function projectPledge(Request $request, $id)\r\n```\r\n\r\nshould be:\r\n\r\n```php\r\npublic function projectEditAction(Request $request, $id)\r\npublic function projectPledgeAction(Request $request, $id)\r\n```\r\n\r\nBecause on twig views, you can \"include\" a controller's rendered result using:\r\n\r\n```jinja\r\n{{ render(controller('AppBundle:ProjectEdit:projectEdit)) }}\r\n```\r\n\r\nIf projectEdit do not finish by Action, this helper will throw an exception.\r\n\r\nd) about security\r\n\r\n=> If you are using $this->getUser() in a controller:\r\n\r\n```php\r\n        $user = $this->getUser();\r\n\r\n        if ($form->isValid()) {\r\n          $user_id = $user->getId();\r\n```\r\n\r\nAlways take care that user is logged in. Restrict your controller using:\r\n\r\n```\r\n@Security(\"has_role('ROLE_USER')\")\r\n```\r\n\r\n=> when entering Edit or Delete actions on projects or steps, this is a requirement to check if the current user\r\ncan actually edit / delete it. Moreover when URL contains incrementable project ids. This is really easy to change\r\nan ID inside an URL before posting a form using any debugging tool.\r\n\r\nExample before editing a project:\r\n\r\n```php\r\n        if ($project_init->getUser()->getId() !== $user->getId()) {\r\n            throw $this->createAccessDeniedException();\r\n        }\r\n```\r\n\r\ne) script termination\r\n\r\n=> never use die() to prematurely stop a script:\r\n\r\n```php\r\n        if ($project->getUser()->getId() <> $user_id)\r\n            die();\r\n```\r\n\r\nThere are lots of components initialized (kernel, logger, profiler, ...) and they perform actions when the request is complete.\r\nIf a page shouldn't be accessed, just `throw $this->createAccessDeniedException();`.\r\n\r\nf) escaping\r\n\r\nThis is not useful to escape twig variables, such as:\r\n\r\n```jinja\r\n{{ project.fullDescription|e }}\r\n```\r\n\r\nTwig already handles it.\r\n\r\nBut! By default, Twig escapes html entities so you need to explicitely escape your variables with the right strategy if they are used in HTML attributes.\r\n\r\n```jinja\r\n... src=\"{{ project.videoUrl|e('html_attr') }}\r\n```\r\n\r\nLook at this example: http://twigfiddle.com/eeje9y\r\n\r\n\r\n2) new features\r\n\r\na) restricted access to blablacar.com google accounts\r\n=> available option from hwi\r\n\r\nb) added flash message capability\r\n=> use $this->success, $this->error, ... to add messages at the top of the screen on success, error etc (try to pledge\r\nany project to see it in action, i didn't implemented it elsewhere at the moment)\r\n\r\nc) added error message handler\r\n=> display a \"beautiful\" message when page crashes instead of the default one. May crash on 404 anyway because base\r\nview uses security stuff, and security is loaded only if routing successes, will see that later.\r\n\r\n3) Please note\r\n\r\na) I didn't remove any image in images, but I guess some of the images are useless (one of you uploaded it when creating\r\na project?), I let you do the cleanup. Now images are uploaded in upload/projects, new git-untracked directory.\r\n\r\nb) Please do a backup of your project before pulling because I started back on a new project and copied/pasted/fixed\r\neverything one by one, so you'll end up with big conflicts. All files have been deleted first, so now-untracked files\r\nwill be removed (parameters.yml included).\r\n\r\nc) When your pull is complete, do a rm -rf app/cache/*, and run a composer update to regenerate your parameters.yml\r\n","created_at":"2015-10-24T16:00:33Z","updated_at":"2015-10-24T16:00:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/chomb94/foundry/pulls/2/commits","review_comments_url":"https://api.github.com/repos/chomb94/foundry/pulls/2/comments","review_comment_url":"https://api.github.com/repos/chomb94/foundry/pulls/comments{/number}","comments_url":"https://api.github.com/repos/chomb94/foundry/issues/2/comments","statuses_url":"https://api.github.com/repos/chomb94/foundry/statuses/de920b8761a5bd9f1a092e29d336eaf76c7fd56e","head":{"label":"ninsuo:master","ref":"master","sha":"de920b8761a5bd9f1a092e29d336eaf76c7fd56e","user":{"login":"ninsuo","id":4152132,"avatar_url":"https://avatars.githubusercontent.com/u/4152132?v=3","gravatar_id":"","url":"https://api.github.com/users/ninsuo","html_url":"https://github.com/ninsuo","followers_url":"https://api.github.com/users/ninsuo/followers","following_url":"https://api.github.com/users/ninsuo/following{/other_user}","gists_url":"https://api.github.com/users/ninsuo/gists{/gist_id}","starred_url":"https://api.github.com/users/ninsuo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ninsuo/subscriptions","organizations_url":"https://api.github.com/users/ninsuo/orgs","repos_url":"https://api.github.com/users/ninsuo/repos","events_url":"https://api.github.com/users/ninsuo/events{/privacy}","received_events_url":"https://api.github.com/users/ninsuo/received_events","type":"User","site_admin":false},"repo":{"id":44638203,"name":"foundry","full_name":"ninsuo/foundry","owner":{"login":"ninsuo","id":4152132,"avatar_url":"https://avatars.githubusercontent.com/u/4152132?v=3","gravatar_id":"","url":"https://api.github.com/users/ninsuo","html_url":"https://github.com/ninsuo","followers_url":"https://api.github.com/users/ninsuo/followers","following_url":"https://api.github.com/users/ninsuo/following{/other_user}","gists_url":"https://api.github.com/users/ninsuo/gists{/gist_id}","starred_url":"https://api.github.com/users/ninsuo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ninsuo/subscriptions","organizations_url":"https://api.github.com/users/ninsuo/orgs","repos_url":"https://api.github.com/users/ninsuo/repos","events_url":"https://api.github.com/users/ninsuo/events{/privacy}","received_events_url":"https://api.github.com/users/ninsuo/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ninsuo/foundry","description":"Crowd founding for company, with no payment","fork":true,"url":"https://api.github.com/repos/ninsuo/foundry","forks_url":"https://api.github.com/repos/ninsuo/foundry/forks","keys_url":"https://api.github.com/repos/ninsuo/foundry/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ninsuo/foundry/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ninsuo/foundry/teams","hooks_url":"https://api.github.com/repos/ninsuo/foundry/hooks","issue_events_url":"https://api.github.com/repos/ninsuo/foundry/issues/events{/number}","events_url":"https://api.github.com/repos/ninsuo/foundry/events","assignees_url":"https://api.github.com/repos/ninsuo/foundry/assignees{/user}","branches_url":"https://api.github.com/repos/ninsuo/foundry/branches{/branch}","tags_url":"https://api.github.com/repos/ninsuo/foundry/tags","blobs_url":"https://api.github.com/repos/ninsuo/foundry/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ninsuo/foundry/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ninsuo/foundry/git/refs{/sha}","trees_url":"https://api.github.com/repos/ninsuo/foundry/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ninsuo/foundry/statuses/{sha}","languages_url":"https://api.github.com/repos/ninsuo/foundry/languages","stargazers_url":"https://api.github.com/repos/ninsuo/foundry/stargazers","contributors_url":"https://api.github.com/repos/ninsuo/foundry/contributors","subscribers_url":"https://api.github.com/repos/ninsuo/foundry/subscribers","subscription_url":"https://api.github.com/repos/ninsuo/foundry/subscription","commits_url":"https://api.github.com/repos/ninsuo/foundry/commits{/sha}","git_commits_url":"https://api.github.com/repos/ninsuo/foundry/git/commits{/sha}","comments_url":"https://api.github.com/repos/ninsuo/foundry/comments{/number}","issue_comment_url":"https://api.github.com/repos/ninsuo/foundry/issues/comments{/number}","contents_url":"https://api.github.com/repos/ninsuo/foundry/contents/{+path}","compare_url":"https://api.github.com/repos/ninsuo/foundry/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ninsuo/foundry/merges","archive_url":"https://api.github.com/repos/ninsuo/foundry/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ninsuo/foundry/downloads","issues_url":"https://api.github.com/repos/ninsuo/foundry/issues{/number}","pulls_url":"https://api.github.com/repos/ninsuo/foundry/pulls{/number}","milestones_url":"https://api.github.com/repos/ninsuo/foundry/milestones{/number}","notifications_url":"https://api.github.com/repos/ninsuo/foundry/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ninsuo/foundry/labels{/name}","releases_url":"https://api.github.com/repos/ninsuo/foundry/releases{/id}","created_at":"2015-10-20T22:20:21Z","updated_at":"2015-10-20T22:20:24Z","pushed_at":"2015-10-24T15:51:11Z","git_url":"git://github.com/ninsuo/foundry.git","ssh_url":"git@github.com:ninsuo/foundry.git","clone_url":"https://github.com/ninsuo/foundry.git","svn_url":"https://github.com/ninsuo/foundry","homepage":null,"size":17117,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"chomb94:master","ref":"master","sha":"eea3df08e8a615a33e75c237dccb66c7cd801f73","user":{"login":"chomb94","id":14362350,"avatar_url":"https://avatars.githubusercontent.com/u/14362350?v=3","gravatar_id":"","url":"https://api.github.com/users/chomb94","html_url":"https://github.com/chomb94","followers_url":"https://api.github.com/users/chomb94/followers","following_url":"https://api.github.com/users/chomb94/following{/other_user}","gists_url":"https://api.github.com/users/chomb94/gists{/gist_id}","starred_url":"https://api.github.com/users/chomb94/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chomb94/subscriptions","organizations_url":"https://api.github.com/users/chomb94/orgs","repos_url":"https://api.github.com/users/chomb94/repos","events_url":"https://api.github.com/users/chomb94/events{/privacy}","received_events_url":"https://api.github.com/users/chomb94/received_events","type":"User","site_admin":false},"repo":{"id":42779756,"name":"foundry","full_name":"chomb94/foundry","owner":{"login":"chomb94","id":14362350,"avatar_url":"https://avatars.githubusercontent.com/u/14362350?v=3","gravatar_id":"","url":"https://api.github.com/users/chomb94","html_url":"https://github.com/chomb94","followers_url":"https://api.github.com/users/chomb94/followers","following_url":"https://api.github.com/users/chomb94/following{/other_user}","gists_url":"https://api.github.com/users/chomb94/gists{/gist_id}","starred_url":"https://api.github.com/users/chomb94/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chomb94/subscriptions","organizations_url":"https://api.github.com/users/chomb94/orgs","repos_url":"https://api.github.com/users/chomb94/repos","events_url":"https://api.github.com/users/chomb94/events{/privacy}","received_events_url":"https://api.github.com/users/chomb94/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/chomb94/foundry","description":"Crowd founding for company, with no payment","fork":false,"url":"https://api.github.com/repos/chomb94/foundry","forks_url":"https://api.github.com/repos/chomb94/foundry/forks","keys_url":"https://api.github.com/repos/chomb94/foundry/keys{/key_id}","collaborators_url":"https://api.github.com/repos/chomb94/foundry/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/chomb94/foundry/teams","hooks_url":"https://api.github.com/repos/chomb94/foundry/hooks","issue_events_url":"https://api.github.com/repos/chomb94/foundry/issues/events{/number}","events_url":"https://api.github.com/repos/chomb94/foundry/events","assignees_url":"https://api.github.com/repos/chomb94/foundry/assignees{/user}","branches_url":"https://api.github.com/repos/chomb94/foundry/branches{/branch}","tags_url":"https://api.github.com/repos/chomb94/foundry/tags","blobs_url":"https://api.github.com/repos/chomb94/foundry/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/chomb94/foundry/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/chomb94/foundry/git/refs{/sha}","trees_url":"https://api.github.com/repos/chomb94/foundry/git/trees{/sha}","statuses_url":"https://api.github.com/repos/chomb94/foundry/statuses/{sha}","languages_url":"https://api.github.com/repos/chomb94/foundry/languages","stargazers_url":"https://api.github.com/repos/chomb94/foundry/stargazers","contributors_url":"https://api.github.com/repos/chomb94/foundry/contributors","subscribers_url":"https://api.github.com/repos/chomb94/foundry/subscribers","subscription_url":"https://api.github.com/repos/chomb94/foundry/subscription","commits_url":"https://api.github.com/repos/chomb94/foundry/commits{/sha}","git_commits_url":"https://api.github.com/repos/chomb94/foundry/git/commits{/sha}","comments_url":"https://api.github.com/repos/chomb94/foundry/comments{/number}","issue_comment_url":"https://api.github.com/repos/chomb94/foundry/issues/comments{/number}","contents_url":"https://api.github.com/repos/chomb94/foundry/contents/{+path}","compare_url":"https://api.github.com/repos/chomb94/foundry/compare/{base}...{head}","merges_url":"https://api.github.com/repos/chomb94/foundry/merges","archive_url":"https://api.github.com/repos/chomb94/foundry/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/chomb94/foundry/downloads","issues_url":"https://api.github.com/repos/chomb94/foundry/issues{/number}","pulls_url":"https://api.github.com/repos/chomb94/foundry/pulls{/number}","milestones_url":"https://api.github.com/repos/chomb94/foundry/milestones{/number}","notifications_url":"https://api.github.com/repos/chomb94/foundry/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/chomb94/foundry/labels{/name}","releases_url":"https://api.github.com/repos/chomb94/foundry/releases{/id}","created_at":"2015-09-19T16:09:53Z","updated_at":"2015-09-19T16:19:23Z","pushed_at":"2015-10-22T11:56:01Z","git_url":"git://github.com/chomb94/foundry.git","ssh_url":"git@github.com:chomb94/foundry.git","clone_url":"https://github.com/chomb94/foundry.git","svn_url":"https://github.com/chomb94/foundry","homepage":null,"size":17295,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":1,"forks":1,"open_issues":1,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/chomb94/foundry/pulls/2"},"html":{"href":"https://github.com/chomb94/foundry/pull/2"},"issue":{"href":"https://api.github.com/repos/chomb94/foundry/issues/2"},"comments":{"href":"https://api.github.com/repos/chomb94/foundry/issues/2/comments"},"review_comments":{"href":"https://api.github.com/repos/chomb94/foundry/pulls/2/comments"},"review_comment":{"href":"https://api.github.com/repos/chomb94/foundry/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/chomb94/foundry/pulls/2/commits"},"statuses":{"href":"https://api.github.com/repos/chomb94/foundry/statuses/de920b8761a5bd9f1a092e29d336eaf76c7fd56e"}},"merged":false,"mergeable":null,"mergeable_state":"unknown","merged_by":null,"comments":0,"review_comments":0,"commits":12,"additions":3140,"deletions":4411,"changed_files":75}}