{"id":2919,"date":"2018-06-25T13:39:50","date_gmt":"2018-06-25T13:39:50","guid":{"rendered":"http:\/\/myprojects.advchaweb.com\/?p=2919"},"modified":"2018-06-25T15:36:13","modified_gmt":"2018-06-25T15:36:13","slug":"symfony-4-blog-app","status":"publish","type":"post","link":"https:\/\/myprojects.advchaweb.com\/index.php\/2018\/06\/25\/symfony-4-blog-app\/","title":{"rendered":"Symfony 4 &#8211; Blog App"},"content":{"rendered":"<p>Ref: https:\/\/auth0.com\/blog\/symfony-tutorial-building-a-blog-part-1\/<br \/>\nhttps:\/\/symfony.com\/doc\/current\/setup.html<\/p>\n<p>Install the latest Symfony 4 via\u00a0Composer\u00a0with the following command:<\/p>\n<pre class=\"lang:default decode:true \">composer create-project symfony\/website-skeleton blog<\/pre>\n<pre class=\"lang:default decode:true\">teddy@teddy:~\/Documents\/works\/symfony4$ composer create-project symfony\/website-skeleton blog\r\nInstalling symfony\/website-skeleton (v4.1.0)\r\n  - Installing symfony\/website-skeleton (v4.1.0): Downloading (100%)         \r\nCreated project in blog\r\nLoading composer repositories with package information\r\nUpdating dependencies (including require-dev)\r\nPackage operations: 92 installs, 0 updates, 0 removals\r\n  - Installing ocramius\/package-versions (1.3.0): Downloading (100%)         \r\n  - Installing symfony\/flex (v1.0.80): Downloading (100%)         \r\n\r\nPrefetching 59 packages \ud83c\udfb6\r\n  - Downloading (100%)\r\n\r\n  - Installing doctrine\/lexer (v1.0.1): Loading from cache\r\n  - Installing doctrine\/inflector (v1.3.0): Loading from cache\r\n  - Installing doctrine\/collections (v1.5.0): Loading from cache\r\n  - Installing doctrine\/cache (v1.7.1): Loading from cache\r\n  - Installing doctrine\/annotations (v1.6.0): Loading from cache\r\n  - Installing doctrine\/common (v2.8.1): Loading from cache\r\n  - Installing symfony\/polyfill-ctype (v1.8.0): Loading from cache\r\n  - Installing symfony\/polyfill-mbstring (v1.8.0): Loading from cache\r\n  - Installing symfony\/http-foundation (v4.1.1): Loading from cache\r\n  - Installing symfony\/event-dispatcher (v4.1.1): Loading from cache\r\n  - Installing psr\/log (1.0.2): Loading from cache\r\n  - Installing symfony\/debug (v4.1.1): Loading from cache\r\n  - Installing symfony\/http-kernel (v4.1.1): Loading from cache\r\n  - Installing symfony\/yaml (v4.1.1): Loading from cache\r\n  - Installing symfony\/webpack-encore-pack (v1.0.2): Loading from cache\r\n  - Installing psr\/link (1.0.0): Loading from cache\r\n  - Installing fig\/link-util (1.0.0): Loading from cache\r\n  - Installing symfony\/web-link (v4.1.1): Loading from cache\r\n  - Installing symfony\/translation (v4.1.1): Loading from cache\r\n  - Installing symfony\/validator (v4.1.1): Loading from cache\r\n  - Installing twig\/twig (v2.4.8): Loading from cache\r\n  - Installing symfony\/twig-bridge (v4.1.1): Loading from cache\r\n  - Installing symfony\/filesystem (v4.1.1): Loading from cache\r\n  - Installing symfony\/config (v4.1.1): Loading from cache\r\n  - Installing symfony\/twig-bundle (v4.1.1): Loading from cache\r\n  - Installing psr\/container (1.0.0): Loading from cache\r\n  - Installing symfony\/dependency-injection (v4.1.1): Loading from cache\r\n  - Installing egulias\/email-validator (2.1.4): Loading from cache\r\n  - Installing swiftmailer\/swiftmailer (v6.0.2): Loading from cache\r\n  - Installing symfony\/swiftmailer-bundle (v3.2.2): Loading from cache\r\n  - Installing symfony\/serializer (v4.1.1): Loading from cache\r\n  - Installing symfony\/inflector (v4.1.1): Loading from cache\r\n  - Installing symfony\/property-info (v4.1.1): Loading from cache\r\n  - Installing symfony\/property-access (v4.1.1): Loading from cache\r\n  - Installing psr\/simple-cache (1.0.1): Loading from cache\r\n  - Installing psr\/cache (1.0.1): Loading from cache\r\n  - Installing symfony\/cache (v4.1.1): Loading from cache\r\n  - Installing webmozart\/assert (1.3.0): Loading from cache\r\n  - Installing phpdocumentor\/reflection-common (1.0.1): Loading from cache\r\n  - Installing phpdocumentor\/type-resolver (0.4.0): Loading from cache\r\n  - Installing phpdocumentor\/reflection-docblock (4.3.0): Loading from cache\r\n  - Installing symfony\/serializer-pack (v1.0.1): Loading from cache\r\n  - Installing symfony\/security (v4.1.1): Loading from cache\r\n  - Installing symfony\/security-bundle (v4.1.1): Loading from cache\r\n  - Installing symfony\/process (v4.1.1): Loading from cache\r\n  - Installing symfony\/routing (v4.1.1): Loading from cache\r\n  - Installing symfony\/finder (v4.1.1): Loading from cache\r\n  - Installing symfony\/framework-bundle (v4.1.1): Loading from cache\r\n  - Installing zendframework\/zend-eventmanager (3.2.1): Loading from cache\r\n  - Installing zendframework\/zend-code (3.3.0): Loading from cache\r\n  - Installing ocramius\/proxy-manager (2.2.0): Loading from cache\r\n  - Installing symfony\/console (v4.1.1): Loading from cache\r\n  - Installing doctrine\/dbal (v2.7.1): Loading from cache\r\n  - Installing doctrine\/migrations (v1.8.1): Loading from cache\r\n  - Installing symfony\/stopwatch (v4.1.1): Loading from cache\r\n  - Installing symfony\/doctrine-bridge (v4.1.1): Loading from cache\r\n  - Installing doctrine\/doctrine-cache-bundle (1.3.3): Loading from cache\r\n  - Installing jdorn\/sql-formatter (v1.2.17): Loading from cache\r\n  - Installing doctrine\/doctrine-bundle (1.9.1): Loading from cache\r\n  - Installing doctrine\/doctrine-migrations-bundle (v1.3.1): Loading from cache\r\n  - Installing doctrine\/instantiator (1.1.0): Loading from cache\r\n  - Installing doctrine\/orm (v2.6.1): Loading from cache\r\n  - Installing symfony\/orm-pack (v1.0.5): Loading from cache\r\n  - Installing monolog\/monolog (1.23.0): Loading from cache\r\n  - Installing symfony\/monolog-bridge (v4.1.1): Loading from cache\r\n  - Installing symfony\/monolog-bundle (v3.3.0): Loading from cache\r\n  - Installing symfony\/options-resolver (v4.1.1): Loading from cache\r\n  - Installing symfony\/intl (v4.1.1): Loading from cache\r\n  - Installing symfony\/polyfill-intl-icu (v1.8.0): Loading from cache\r\n  - Installing symfony\/form (v4.1.1): Loading from cache\r\n  - Installing symfony\/expression-language (v4.1.1): Loading from cache\r\n  - Installing symfony\/asset (v4.1.1): Loading from cache\r\n  - Installing sensio\/framework-extra-bundle (v5.1.6): Loading from cache\r\n  - Installing symfony\/polyfill-php72 (v1.8.0): Loading from cache\r\n  - Installing symfony\/var-dumper (v4.1.1): Loading from cache\r\n  - Installing symfony\/web-profiler-bundle (v4.1.1): Loading from cache\r\n  - Installing symfony\/profiler-pack (v1.0.3): Loading from cache\r\n  - Installing easycorp\/easy-log-handler (v1.0.5): Loading from cache\r\n  - Installing symfony\/debug-bundle (v4.1.1): Loading from cache\r\n  - Installing symfony\/debug-pack (v1.0.5): Loading from cache\r\n  - Installing symfony\/dotenv (v4.1.1): Loading from cache\r\n  - Installing nikic\/php-parser (v4.0.2): Loading from cache\r\n  - Installing symfony\/maker-bundle (v1.5.0): Loading from cache\r\n  - Installing symfony\/phpunit-bridge (v4.1.1): Loading from cache\r\n  - Installing symfony\/css-selector (v4.1.1): Loading from cache\r\n  - Installing symfony\/dom-crawler (v4.1.1): Loading from cache\r\n  - Installing symfony\/browser-kit (v4.1.1): Loading from cache\r\n  - Installing symfony\/test-pack (v1.0.2): Loading from cache\r\n  - Installing symfony\/web-server-bundle (v4.1.1): Loading from cache\r\nWriting lock file\r\nGenerating autoload files\r\nocramius\/package-versions:  Generating version class...\r\nocramius\/package-versions: ...done generating version class\r\nSymfony operations: 21 recipes (2a2112973248c715b69c3d31ba4e5d87)\r\n  - Configuring symfony\/flex (&gt;=1.0): From github.com\/symfony\/recipes:master\r\n  - Configuring symfony\/framework-bundle (&gt;=3.3): From github.com\/symfony\/recipes:master\r\n  - Configuring doctrine\/annotations (&gt;=1.0): From github.com\/symfony\/recipes:master\r\n  - Configuring symfony\/webpack-encore-pack (&gt;=1.0): From github.com\/symfony\/recipes:master\r\n  - Configuring symfony\/translation (&gt;=3.3): From github.com\/symfony\/recipes:master\r\n  - Configuring symfony\/twig-bundle (&gt;=3.3): From github.com\/symfony\/recipes:master\r\n  - Configuring symfony\/swiftmailer-bundle (&gt;=2.5): From github.com\/symfony\/recipes:master\r\n  - Configuring symfony\/security-bundle (&gt;=3.3): From github.com\/symfony\/recipes:master\r\n  - Configuring symfony\/routing (&gt;=4.0): From github.com\/symfony\/recipes:master\r\n  - Configuring symfony\/console (&gt;=3.3): From github.com\/symfony\/recipes:master\r\n  - Configuring doctrine\/doctrine-cache-bundle (&gt;=1.3.3): From auto-generated recipe\r\n  - Configuring doctrine\/doctrine-bundle (&gt;=1.6): From github.com\/symfony\/recipes:master\r\n  - Configuring doctrine\/doctrine-migrations-bundle (&gt;=1.2): From github.com\/symfony\/recipes:master\r\n  - Configuring symfony\/monolog-bundle (&gt;=3.1): From github.com\/symfony\/recipes:master\r\n  - Configuring sensio\/framework-extra-bundle (&gt;=4.0): From github.com\/symfony\/recipes:master\r\n  - Configuring symfony\/web-profiler-bundle (&gt;=3.3): From github.com\/symfony\/recipes:master\r\n  - Configuring easycorp\/easy-log-handler (&gt;=1.0): From github.com\/symfony\/recipes:master\r\n  - Configuring symfony\/debug-bundle (&gt;=4.1): From github.com\/symfony\/recipes:master\r\n  - Configuring symfony\/maker-bundle (&gt;=1.0): From github.com\/symfony\/recipes:master\r\n  - Configuring symfony\/phpunit-bridge (&gt;=4.1): From github.com\/symfony\/recipes:master\r\n  - Configuring symfony\/web-server-bundle (&gt;=3.3): From github.com\/symfony\/recipes:master\r\nExecuting script cache:clear [OK]\r\nExecuting script assets:install public [OK]\r\n\r\nSome files may have been created or updated to configure your new packages.\r\nPlease review, edit and commit them: these files are yours.\r\n\r\n              \r\n What's next? \r\n              \r\n\r\n  * Run your application:\r\n    1. Change to the project directory\r\n    2. Create your code repository with the git init command\r\n    3. Execute the php -S 127.0.0.1:8000 -t public command\r\n    4. Browse to the http:\/\/localhost:8000\/ URL.\r\n\r\n       Quit the server with CTRL-C.\r\n       Run composer require server --dev for a better web server.\r\n\r\n  * Read the documentation at https:\/\/symfony.com\/doc\r\n\r\n                        \r\n Database Configuration \r\n                        \r\n\r\n  * Modify your DATABASE_URL config in .env\r\n\r\n  * Configure the driver (mysql) and\r\n    server_version (5.7) in config\/packages\/doctrine.yaml\r\n\r\n              \r\n How to test? \r\n              \r\n\r\n  * Write test cases in the tests\/ folder\r\n  * Run php bin\/phpunit<\/pre>\n<p>Update DotEnv File<br \/>\nIn your root directory, there is a file called\u00a0.env (usually this file is hidden. so set your system to show the hidden files), you should see something similar to the following:<\/p>\n<pre class=\"lang:default decode:true \">...\r\n# Configure your db driver and server_version in config\/packages\/doctrine.yaml\r\nDATABASE_URL=mysql:\/\/db_user:db_password@127.0.0.1:3306\/db_name\r\n###&lt; doctrine\/doctrine-bundle ###<\/pre>\n<p>Change to this:<\/p>\n<pre class=\"lang:default decode:true \">DATABASE_URL=mysql:\/\/root:teddy@127.0.0.1:3306\/symfony4_blog<\/pre>\n<p>run the following command<\/p>\n<pre class=\"lang:default decode:true \">php bin\/console doctrine:database:create<\/pre>\n<p>which will create a database with the value of your database name.<br \/>\n&lt;!&#8211; START SKIP &#8211;&gt;<br \/>\nIF YOU GOT ERROR LIKE MINE. IT&#8217;S BECAUSE MY PHP SETTING &amp; APACHE2\/NGINX SERVER DIDN&#8217;T WORK WELL. SKIP IT IF YOU DONT HAVE ANY ERROR LIKE THIS :<\/p>\n<pre class=\"lang:default decode:true \">teddy@teddy:~\/Documents\/works\/symfony4$ cd blog\/\r\nteddy@teddy:~\/Documents\/works\/symfony4\/blog$ php bin\/console doctrine:database:create\r\n\r\nIn AbstractMySQLDriver.php line 125:\r\n                                                          \r\n  An exception occurred in driver: could not find driver  \r\n                                                          \r\n\r\nIn PDOConnection.php line 50:\r\n                         \r\n  could not find driver  \r\n                         \r\n\r\nIn PDOConnection.php line 46:\r\n                         \r\n  could not find driver  \r\n                         \r\n\r\ndoctrine:database:create [--shard SHARD] [--connection [CONNECTION]] [--if-not-exists] [-h|--help] [-q|--quiet] [-v|vv|vvv|--verbose] [-V|--version] [--ansi] [--no-ansi] [-n|--no-interaction] [-e|--env ENV] [--no-debug] [--] &lt;command&gt;\r\n<\/pre>\n<p>I NEED TO CHECK MY PHP VERSION. CLI ALREADY 7.2.<\/p>\n<pre class=\"lang:default decode:true \">teddy@teddy:~\/Documents\/works\/symfony4\/blog$ php -v\r\nPHP 7.2.7-1+ubuntu16.04.1+deb.sury.org+1 (cli) (built: Jun 22 2018 08:44:50) ( NTS )\r\nCopyright (c) 1997-2018 The PHP Group\r\nZend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies\r\n    with Zend OPcache v7.2.7-1+ubuntu16.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies\r\n    with Xdebug v2.6.0, Copyright (c) 2002-2018, by Derick Rethan<\/pre>\n<p>BUT THE SERVER STILL 7.0 (http:\/\/localhost\/phpinfo.php). I ALREADY HAS 7.2 BUT SOME EXTENSIONS ARE MISSING. SO INSTALL THEM<\/p>\n<pre class=\"lang:default decode:true \">sudo apt-get install php7.2-mysql php7.2-curl php7.2-cgi php7.2-mbstring php-mcrypt php7.2-zip php7.2-fpm php7.2-xml php7.2-xmlrpc php-xdebug php7.2-intl<\/pre>\n<p>TO ENABLE PHP 7.2 ON APACHE2 SERVER, PLS DO (MAKE SURE NGINX IS STOPPED IF IT&#8217;S RUNNING AND START APACHE2):<\/p>\n<pre class=\"lang:default decode:true \">sudo a2dismod php7.0\r\nsudo a2dismod php7.1\r\nsudo a2enmod php7.2\r\nsudo systemctl restart apache2<\/pre>\n<p>TEST: http:\/\/localhost\/phpinfo.php<\/p>\n<p>IF NEEDED TO CHANGE THE PHP SETTING, PLS EDIT:<\/p>\n<pre class=\"lang:default decode:true\">sudo gedit \/etc\/php\/7.2\/apache2\/php.ini<\/pre>\n<pre class=\"lang:default decode:true \">upload_max_filesize = 2000M -&gt; (default 2M)\r\nmax_file_uploads = 2000 -&gt; (default 20)\r\npost_max_size = 2000M -&gt; (default 8M)\r\nmax_execution_time = 600 -&gt; (default 30) in second\r\nmax_input_time = 600 -&gt; (default 60) in second\r\nmemory_limit = 2560M -&gt; (default 128M)<\/pre>\n<p>TO ENABLE PHP 7.2 ON NGINX SERVER, PLS DO (MAKE SURE APACHE2 IS STOPPED IF IT&#8217;S RUNNING AND START NGINX):<\/p>\n<p>THE NGINX MAIN CONFIG IN \/etc\/nginx\/nginx.conf<br \/>\nTHE DEFAULT VIRTUALHOST IN \/etc\/nginx\/sites-available\/default<br \/>\nEDIT IT TO ENABLE PARSING PHP FILE:<\/p>\n<pre class=\"lang:default decode:true \">sudo gedit \/etc\/nginx\/sites-available\/default<\/pre>\n<p>CHANGE THE CONTENT TO ENABLE PHP 7.2 FPM:<\/p>\n<pre class=\"lang:default decode:true \">...\r\nserver {\r\n        ...\r\n        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000\r\n\t#\r\n\tlocation ~ \\.php$ {\r\n\t\tinclude snippets\/fastcgi-php.conf;\r\n\t#\r\n\t#\t# With php7.0-cgi alone:\r\n\t#\tfastcgi_pass 127.0.0.1:9000;\r\n\t#\t# With php7.0-fpm:\r\n\t\tfastcgi_pass unix:\/run\/php\/php7.2-fpm.sock;\r\n\t}\r\n\r\n\t# deny access to .htaccess files, if Apache's document root\r\n\t# concurs with nginx's one\r\n\t#\r\n\tlocation ~ \/\\.ht {\r\n\t\tdeny all;\r\n\t}\r\n}\r\n...<\/pre>\n<p>THEN CHANGE PHP7.2-FPM SETTING:<\/p>\n<pre class=\"lang:default decode:true \">sudo gedit \/etc\/php\/7.2\/fpm\/php.ini<\/pre>\n<p>CHANGE THE CONTENT:<\/p>\n<pre class=\"lang:default decode:true \">cgi.fix_pathinfo=0\r\nupload_max_filesize = 2000M -&gt; (default 2M)\r\nmax_file_uploads = 2000 -&gt; (default 20)\r\npost_max_size = 2000M -&gt; (default 8M)\r\nmax_execution_time = 6000 -&gt; (default 30) in second\r\nmax_input_time = 600 -&gt; (default 60) in second\r\nmemory_limit = 2560M -&gt; (default 128M)<\/pre>\n<p>THEN RESTART PHP7.2-FPM SERVICE:<\/p>\n<pre class=\"lang:default decode:true \">sudo systemctl restart php7.2-fpm<\/pre>\n<p>CHECK NGINX SYNTAX: sudo nginx -t<br \/>\nRESTART NGINX: sudo systemctl restart nginx<br \/>\nOPEN IT: http:\/\/localhost\/phpinfo.php (NEED TO CLEAR THE BROWSER CACHE FIRST)<br \/>\n&lt;!&#8211; END SKIP &#8211;&gt;<\/p>\n<p>OK. I FIXED THE CREATION DATABASE ERROR. RUN AGAIN<\/p>\n<pre class=\"lang:default decode:true \">php bin\/console doctrine:database:create<\/pre>\n<p>HERE IS THE WORKING RESULT:<\/p>\n<pre class=\"lang:default decode:true \">teddy@teddy:~\/Documents\/works\/symfony4\/blog$ php bin\/console doctrine:database:create\r\nCreated database `symfony4_blog` for connection named default<\/pre>\n<p>Create the Blog Controller<br \/>\nCreate new\u00a0BlogController\u00a0by running the following command<\/p>\n<pre class=\"lang:default decode:true \">php bin\/console make:controller<\/pre>\n<p>When it asks for\u00a0The class name of the controller to create, type in:\u00a0BlogController.<\/p>\n<pre class=\"lang:default decode:true\">teddy@teddy:~\/Documents\/works\/symfony4\/blog$ php bin\/console make:controller\r\n\r\n Choose a name for your controller class (e.g. FierceKangarooController):\r\n &gt; BlogController\r\n\r\n created: src\/Controller\/BlogController.php\r\n created: templates\/blog\/index.html.twig\r\n\r\n           \r\n  Success! \r\n           \r\n\r\n Next: Open your new controller class and add some pages!<\/pre>\n<p>THEN CHANGE THE ROUTE IN src\/Controller\/BlogController.php<br \/>\nFROM:<\/p>\n<pre class=\"lang:default decode:true\">\/**\r\n* @Route(\"\/blog\", name=\"blog\")\r\n*\/<\/pre>\n<p>TO:<\/p>\n<pre class=\"lang:default decode:true \">\/**\r\n* @Route(\"\/\", name=\"homepage\")\r\n*\/<\/pre>\n<p>THEN TEST IT VIA SYMFONY WEB SERVER. RUN:<\/p>\n<pre class=\"lang:default decode:true\">teddy@teddy:~\/Documents\/works\/symfony4\/blog$ php bin\/console server:run\r\n\r\n                                                                                \r\n [OK] Server listening on http:\/\/127.0.0.1:8000                                 \r\n                                                                                \r\n\r\n \/\/ Quit the server with CONTROL-C.                                             \r\n\r\nPHP 7.2.7-1+ubuntu16.04.1+deb.sury.org+1 Development Server started at Mon Jun 25 21:57:17 2018\r\nListening on http:\/\/127.0.0.1:8000\r\nDocument root is \/home\/teddy\/Documents\/works\/symfony4\/blog\/public\r\nPress Ctrl-C to quit.\r\n[Mon Jun 25 21:57:32 2018] 127.0.0.1:39972 [200]: \/\r\n[Mon Jun 25 21:57:33 2018] 127.0.0.1:39974 [200]: \/_wdt\/675573\r\n[Mon Jun 25 21:57:33 2018] 127.0.0.1:39976 [404]: \/favicon.ico<\/pre>\n<p>OPEN IT ON YOUR BROWSER: http:\/\/127.0.0.1:8000<br \/>\nTHEN you&#8217;ll be shown a\u00a0Hello BlogController!\u00a0page.<\/p>\n<p>Creating a New Author Entity<br \/>\nCreate new\u00a0Author\u00a0entity by running the following command:<\/p>\n<pre class=\"lang:default decode:true \">php bin\/console make:entity<\/pre>\n<pre class=\"lang:default decode:true\">teddy@teddy:~\/Documents\/works\/symfony4\/blog$ php bin\/console make:entity\r\n\r\n Class name of the entity to create or update (e.g. DeliciousGnome):\r\n &gt; Author\r\n\r\n created: src\/Entity\/Author.php\r\n created: src\/Repository\/AuthorRepository.php\r\n \r\n Entity generated! Now let's add some fields!\r\n You can always add more fields later manually or by re-running this command.\r\n\r\n New property name (press &lt;return&gt; to stop adding fields):\r\n &gt; \r\n\r\n\r\n           \r\n  Success! \r\n           \r\n\r\n Next: When you're ready, create a migration with make:migration<\/pre>\n<p>OPEN A PHP FILE\u00a0 src\/Entity\/Author.php, THEN REPLACE IT.<br \/>\nFROM:<\/p>\n<pre class=\"lang:default decode:true \">&lt;?php\r\n\r\nnamespace App\\Entity;\r\n\r\nuse Doctrine\\ORM\\Mapping as ORM;\r\n\r\n\/**\r\n * @ORM\\Entity(repositoryClass=\"App\\Repository\\AuthorRepository\")\r\n *\/\r\nclass Author\r\n{\r\n    \/**\r\n     * @ORM\\Id()\r\n     * @ORM\\GeneratedValue()\r\n     * @ORM\\Column(type=\"integer\")\r\n     *\/\r\n    private $id;\r\n\r\n    public function getId()\r\n    {\r\n        return $this-&gt;id;\r\n    }\r\n}<\/pre>\n<p>TO:<\/p>\n<pre class=\"lang:default decode:true \">&lt;?php\r\n\r\nnamespace App\\Entity;\r\n\r\nuse Doctrine\\ORM\\Mapping as ORM;\r\n\r\n\/**\r\n * Author\r\n *\r\n * @ORM\\Table(name=\"author\")\r\n * @ORM\\Entity(repositoryClass=\"App\\Repository\\AuthorRepository\")\r\n *\/\r\nclass Author\r\n{\r\n    \/**\r\n     * @var int\r\n     *\r\n     * @ORM\\Column(name=\"id\", type=\"integer\")\r\n     * @ORM\\Id\r\n     * @ORM\\GeneratedValue(strategy=\"AUTO\")\r\n     *\/\r\n    private $id;\r\n\r\n    \/**\r\n     * @var string\r\n     *\r\n     * @ORM\\Column(name=\"name\", type=\"string\", length=255, unique=true)\r\n     *\/\r\n    private $name;\r\n\r\n    \/**\r\n     * @var string\r\n     *\r\n     * @ORM\\Column(name=\"title\", type=\"string\", length=255)\r\n     *\/\r\n    private $title;\r\n\r\n    \/**\r\n     * @var string\r\n     *\r\n     * @ORM\\Column(name=\"username\", type=\"string\", length=255, unique=true)\r\n     *\/\r\n    private $username;\r\n\r\n    \/**\r\n     * @var string\r\n     *\r\n     * @ORM\\Column(name=\"company\", type=\"string\", length=255)\r\n     *\/\r\n    private $company;\r\n\r\n    \/**\r\n     * @var string\r\n     *\r\n     * @ORM\\Column(name=\"short_bio\", type=\"string\", length=500)\r\n     *\/\r\n    private $shortBio;\r\n\r\n    \/**\r\n     * @var string\r\n     *\r\n     * @ORM\\Column(name=\"phone\", type=\"string\", length=255, nullable=true)\r\n     *\/\r\n    private $phone;\r\n\r\n    \/**\r\n     * @var string\r\n     *\r\n     * @ORM\\Column(name=\"facebook\", type=\"string\", length=255, nullable=true)\r\n     *\/\r\n    private $facebook;\r\n\r\n    \/**\r\n     * @var string\r\n     *\r\n     * @ORM\\Column(name=\"twitter\", type=\"string\", length=255, nullable=true)\r\n     *\/\r\n    private $twitter;\r\n\r\n    \/**\r\n     * @var string\r\n     *\r\n     * @ORM\\Column(name=\"github\", type=\"string\", length=255, nullable=true)\r\n     *\/\r\n    private $github;\r\n\r\n\r\n    \/**\r\n     * Get id\r\n     *\r\n     * @return int\r\n     *\/\r\n    public function getId()\r\n    {\r\n        return $this-&gt;id;\r\n    }\r\n\r\n    \/**\r\n     * Set name\r\n     *\r\n     * @param string $name\r\n     *\r\n     * @return Author\r\n     *\/\r\n    public function setName($name)\r\n    {\r\n        $this-&gt;name = $name;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get name\r\n     *\r\n     * @return string\r\n     *\/\r\n    public function getName()\r\n    {\r\n        return $this-&gt;name;\r\n    }\r\n\r\n    \/**\r\n     * Set title\r\n     *\r\n     * @param string $title\r\n     *\r\n     * @return Author\r\n     *\/\r\n    public function setTitle($title)\r\n    {\r\n        $this-&gt;title = $title;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get title\r\n     *\r\n     * @return string\r\n     *\/\r\n    public function getTitle()\r\n    {\r\n        return $this-&gt;title;\r\n    }\r\n\r\n    \/**\r\n     * Set username\r\n     *\r\n     * @param string $username\r\n     *\r\n     * @return Author\r\n     *\/\r\n    public function setUsername($username)\r\n    {\r\n        $this-&gt;username = $username;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get username\r\n     *\r\n     * @return string\r\n     *\/\r\n    public function getUsername()\r\n    {\r\n        return $this-&gt;username;\r\n    }\r\n\r\n    \/**\r\n     * Set company\r\n     *\r\n     * @param string $company\r\n     *\r\n     * @return Author\r\n     *\/\r\n    public function setCompany($company)\r\n    {\r\n        $this-&gt;company = $company;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get company\r\n     *\r\n     * @return string\r\n     *\/\r\n    public function getCompany()\r\n    {\r\n        return $this-&gt;company;\r\n    }\r\n\r\n    \/**\r\n     * Set shortBio\r\n     *\r\n     * @param string $shortBio\r\n     *\r\n     * @return Author\r\n     *\/\r\n    public function setShortBio($shortBio)\r\n    {\r\n        $this-&gt;shortBio = $shortBio;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get shortBio\r\n     *\r\n     * @return string\r\n     *\/\r\n    public function getShortBio()\r\n    {\r\n        return $this-&gt;shortBio;\r\n    }\r\n\r\n    \/**\r\n     * Set phone\r\n     *\r\n     * @param string $phone\r\n     *\r\n     * @return Author\r\n     *\/\r\n    public function setPhone($phone)\r\n    {\r\n        $this-&gt;phone = $phone;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get phone\r\n     *\r\n     * @return string\r\n     *\/\r\n    public function getPhone()\r\n    {\r\n        return $this-&gt;phone;\r\n    }\r\n\r\n    \/**\r\n     * Set facebook\r\n     *\r\n     * @param string $facebook\r\n     *\r\n     * @return Author\r\n     *\/\r\n    public function setFacebook($facebook)\r\n    {\r\n        $this-&gt;facebook = $facebook;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get facebook\r\n     *\r\n     * @return string\r\n     *\/\r\n    public function getFacebook()\r\n    {\r\n        return $this-&gt;facebook;\r\n    }\r\n\r\n    \/**\r\n     * Set twitter\r\n     *\r\n     * @param string $twitter\r\n     *\r\n     * @return Author\r\n     *\/\r\n    public function setTwitter($twitter)\r\n    {\r\n        $this-&gt;twitter = $twitter;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get twitter\r\n     *\r\n     * @return string\r\n     *\/\r\n    public function getTwitter()\r\n    {\r\n        return $this-&gt;twitter;\r\n    }\r\n\r\n    \/**\r\n     * Set github\r\n     *\r\n     * @param string $github\r\n     *\r\n     * @return Author\r\n     *\/\r\n    public function setGithub($github)\r\n    {\r\n        $this-&gt;github = $github;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get github\r\n     *\r\n     * @return string\r\n     *\/\r\n    public function getGithub()\r\n    {\r\n        return $this-&gt;github;\r\n    }\r\n}<\/pre>\n<p>Creating a New BlogPost Entity<br \/>\nCreate new\u00a0BlogPost\u00a0entity by running the following command\u00a0php<\/p>\n<pre class=\"lang:default decode:true \">bin\/console make:entity<\/pre>\n<p>When it asks for\u00a0The class name of the entity to create, type in:\u00a0BlogPost.<\/p>\n<pre class=\"lang:default decode:true \">teddy@teddy:~\/Documents\/works\/symfony4\/blog$ php bin\/console make:entity\r\n\r\n Class name of the entity to create or update (e.g. OrangePizza):\r\n &gt; BlogPost\r\n\r\n created: src\/Entity\/BlogPost.php\r\n created: src\/Repository\/BlogPostRepository.php\r\n \r\n Entity generated! Now let's add some fields!\r\n You can always add more fields later manually or by re-running this command.\r\n\r\n New property name (press &lt;return&gt; to stop adding fields):\r\n &gt; \r\n\r\n\r\n           \r\n  Success! \r\n           \r\n\r\n Next: When you're ready, create a migration with make:migration<\/pre>\n<p>Once the command has finished running, you&#8217;ll find a new file in\u00a0src\/Entity called\u00a0BlogPost.php. Open this and configure it like so:<\/p>\n<pre class=\"lang:default decode:true \">&lt;?php\r\n\r\nnamespace App\\Entity;\r\n\r\nuse Doctrine\\ORM\\Mapping as ORM;\r\n\r\n\/**\r\n * BlogPost\r\n *\r\n * @ORM\\Table(name=\"blog_post\")\r\n * @ORM\\Entity(repositoryClass=\"App\\Repository\\BlogPostRepository\")\r\n * @ORM\\HasLifecycleCallbacks\r\n *\/\r\nclass BlogPost\r\n{\r\n    \/**\r\n     * @var int\r\n     *\r\n     * @ORM\\Column(name=\"id\", type=\"integer\")\r\n     * @ORM\\Id\r\n     * @ORM\\GeneratedValue(strategy=\"AUTO\")\r\n     *\/\r\n    private $id;\r\n\r\n    \/**\r\n     * @var string\r\n     *\r\n     * @ORM\\Column(name=\"title\", type=\"string\", length=255)\r\n     *\/\r\n    private $title;\r\n\r\n    \/**\r\n     * @var string\r\n     *\r\n     * @ORM\\Column(name=\"slug\", type=\"string\", length=255, unique=true)\r\n     *\/\r\n    private $slug;\r\n\r\n    \/**\r\n     * @var string\r\n     *\r\n     * @ORM\\Column(name=\"description\", type=\"string\", length=2000)\r\n     *\/\r\n    private $description;\r\n\r\n    \/**\r\n     * @var string\r\n     *\r\n     * @ORM\\Column(name=\"body\", type=\"text\")\r\n     *\/\r\n    private $body;\r\n\r\n    \/**\r\n     * @var Author\r\n     *\r\n     * @ORM\\ManyToOne(targetEntity=\"Author\")\r\n     * @ORM\\JoinColumn(name=\"author_id\", referencedColumnName=\"id\")\r\n     *\/\r\n    private $author;\r\n\r\n    \/**\r\n     * @var \\DateTime\r\n     *\r\n     * @ORM\\Column(name=\"created_at\", type=\"datetimetz\")\r\n     *\/\r\n    private $createdAt;\r\n\r\n    \/**\r\n     * @var \\DateTime\r\n     *\r\n     * @ORM\\Column(name=\"updated_at\", type=\"datetime\")\r\n     *\/\r\n    private $updatedAt;\r\n\r\n\r\n    \/**\r\n     * Get id\r\n     *\r\n     * @return int\r\n     *\/\r\n    public function getId()\r\n    {\r\n        return $this-&gt;id;\r\n    }\r\n\r\n    \/**\r\n     * Set title\r\n     *\r\n     * @param string $title\r\n     *\r\n     * @return BlogPost\r\n     *\/\r\n    public function setTitle($title)\r\n    {\r\n        $this-&gt;title = $title;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get title\r\n     *\r\n     * @return string\r\n     *\/\r\n    public function getTitle()\r\n    {\r\n        return $this-&gt;title;\r\n    }\r\n\r\n    \/**\r\n     * Set slug\r\n     *\r\n     * @param string $slug\r\n     *\r\n     * @return BlogPost\r\n     *\/\r\n    public function setSlug($slug)\r\n    {\r\n        $this-&gt;slug = $slug;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get slug\r\n     *\r\n     * @return string\r\n     *\/\r\n    public function getSlug()\r\n    {\r\n        return $this-&gt;slug;\r\n    }\r\n\r\n    \/**\r\n     * Set description\r\n     *\r\n     * @param string $description\r\n     *\r\n     * @return BlogPost\r\n     *\/\r\n    public function setDescription($description)\r\n    {\r\n        $this-&gt;description = $description;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get description\r\n     *\r\n     * @return string\r\n     *\/\r\n    public function getDescription()\r\n    {\r\n        return $this-&gt;description;\r\n    }\r\n\r\n    \/**\r\n     * Set body\r\n     *\r\n     * @param string $body\r\n     *\r\n     * @return BlogPost\r\n     *\/\r\n    public function setBody($body)\r\n    {\r\n        $this-&gt;body = $body;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get body\r\n     *\r\n     * @return string\r\n     *\/\r\n    public function getBody()\r\n    {\r\n        return $this-&gt;body;\r\n    }\r\n\r\n    \/**\r\n     * Set author\r\n     *\r\n     * @param Author $author\r\n     *\r\n     * @return BlogPost\r\n     *\/\r\n    public function setAuthor(Author $author)\r\n    {\r\n        $this-&gt;author = $author;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get author\r\n     *\r\n     * @return Author\r\n     *\/\r\n    public function getAuthor()\r\n    {\r\n        return $this-&gt;author;\r\n    }\r\n\r\n    \/**\r\n     * Set createdAt\r\n     *\r\n     * @param \\DateTime $createdAt\r\n     *\r\n     * @return BlogPost\r\n     *\/\r\n    public function setCreatedAt($createdAt)\r\n    {\r\n        $this-&gt;createdAt = $createdAt;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get createdAt\r\n     *\r\n     * @return \\DateTime\r\n     *\/\r\n    public function getCreatedAt()\r\n    {\r\n        return $this-&gt;createdAt;\r\n    }\r\n\r\n    \/**\r\n     * Set updatedAt\r\n     *\r\n     * @param \\DateTime $updatedAt\r\n     *\r\n     * @return BlogPost\r\n     *\/\r\n    public function setUpdatedAt($updatedAt)\r\n    {\r\n        $this-&gt;updatedAt = $updatedAt;\r\n\r\n        return $this;\r\n    }\r\n\r\n    \/**\r\n     * Get updatedAt\r\n     *\r\n     * @return \\DateTime\r\n     *\/\r\n    public function getUpdatedAt()\r\n    {\r\n        return $this-&gt;updatedAt;\r\n    }\r\n\r\n    \/**\r\n     * @ORM\\PrePersist\r\n     *\/\r\n    public function prePersist()\r\n    {\r\n        if (!$this-&gt;getCreatedAt()) {\r\n            $this-&gt;setCreatedAt(new \\DateTime());\r\n        }\r\n\r\n        if (!$this-&gt;getUpdatedAt()) {\r\n            $this-&gt;setUpdatedAt(new \\DateTime());\r\n        }\r\n    }\r\n\r\n    \/**\r\n     * @ORM\\PreUpdate\r\n     *\/\r\n    public function preUpdate()\r\n    {\r\n        $this-&gt;setUpdatedAt(new \\DateTime());\r\n    }\r\n}<\/pre>\n<p>Although you have created these entities, your database still has no tables in there. Based off these entities, Doctrine can create the tables we&#8217;ve specified. In order to do this, all you have to do is run:<\/p>\n<pre class=\"lang:default decode:true \">php bin\/console doctrine:schema:update --force<\/pre>\n<pre class=\"lang:default decode:true \">teddy@teddy:~\/Documents\/works\/symfony4\/blog$ php bin\/console doctrine:schema:update --force\r\n\r\n Updating database schema...\r\n\r\n     3 queries were executed\r\n\r\n                                                                                \r\n [OK] Database schema updated successfully!<\/pre>\n<p>Install Doctrine-Fixtures<br \/>\nWe want to just populate some data into the newly created tables as examples during the creation of the blog. So install\u00a0doctrine-fixtures.<\/p>\n<pre class=\"lang:default decode:true \">teddy@teddy:~\/Documents\/works\/symfony4\/blog$ composer require --dev doctrine\/doctrine-fixtures-bundle\r\nUsing version ^3.0 for doctrine\/doctrine-fixtures-bundle\r\n.\/composer.json has been updated\r\nLoading composer repositories with package information\r\nUpdating dependencies (including require-dev)\r\n\r\nPrefetching 2 packages \ud83c\udfb6\r\n  - Downloading (100%)\r\n\r\nPackage operations: 2 installs, 0 updates, 0 removals\r\n  - Installing doctrine\/data-fixtures (v1.3.1): Loading from cache\r\n  - Installing doctrine\/doctrine-fixtures-bundle (3.0.2): Loading from cache\r\nWriting lock file\r\nGenerating autoload files\r\nocramius\/package-versions:  Generating version class...\r\nocramius\/package-versions: ...done generating version class\r\nSymfony operations: 1 recipe (77fb7f8c687c54f4792ae78c50b1ea23)\r\n  - Configuring doctrine\/doctrine-fixtures-bundle (&gt;=3.0): From github.com\/symfony\/recipes:master\r\nExecuting script cache:clear [OK]\r\nExecuting script assets:install public [OK]\r\n\r\nSome files may have been created or updated to configure your new packages.\r\nPlease review, edit and commit them: these files are yours.<\/pre>\n<p>Create Author and BlogPost Fixtures<br \/>\nCreate a new file (and the directories the file is stored in) under src\/DataFixtures\/ORM\/Fixtures.php and insert the following into the file:<\/p>\n<pre class=\"lang:default decode:true \">&lt;?php\r\n\r\nnamespace App\\DataFixtures\\ORM;\r\n\r\nuse App\\Entity\\Author;\r\nuse App\\Entity\\BlogPost;\r\nuse Doctrine\\Bundle\\FixturesBundle\\Fixture;\r\nuse Doctrine\\Common\\Persistence\\ObjectManager;\r\n\r\nclass Fixtures extends Fixture\r\n{\r\n    public function load(ObjectManager $manager)\r\n    {\r\n        $author = new Author();\r\n        $author\r\n            -&gt;setName('Joe Bloggs')\r\n            -&gt;setTitle('Developer')\r\n            -&gt;setUsername('auth0-username')\r\n            -&gt;setCompany('The Writing Company')\r\n            -&gt;setShortBio('Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages.')\r\n            -&gt;setPhone('070000000')\r\n            -&gt;setFacebook('joebloggs')\r\n            -&gt;setTwitter('joe.bloggs')\r\n            -&gt;setGithub('joe-bloggs');\r\n\r\n        $manager-&gt;persist($author);\r\n\r\n        $blogPost = new BlogPost();\r\n        $blogPost\r\n            -&gt;setTitle('Your first blog post example')\r\n            -&gt;setSlug('first-post')\r\n            -&gt;setDescription('Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.')\r\n            -&gt;setBody('Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of \"de Finibus Bonorum et Malorum\" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, \"Lorem ipsum dolor sit amet..\", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from \"de Finibus Bonorum et Malorum\" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.')\r\n            -&gt;setAuthor($author);\r\n        $manager-&gt;persist($blogPost);\r\n        $manager-&gt;flush();\r\n    }\r\n}<\/pre>\n<p>Running Fixtures<br \/>\nLet&#8217;s run the fixtures!\u00a0php bin\/console doctrine:fixtures:load<\/p>\n<pre class=\"lang:default decode:true \">teddy@teddy:~\/Documents\/works\/symfony4\/blog$ php bin\/console doctrine:fixtures:load\r\nCareful, database will be purged. Do you want to continue y\/N ?y\r\n  &gt; purging database\r\n  &gt; loading App\\DataFixtures\\ORM\\Fixtures<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ref: https:\/\/auth0.com\/blog\/symfony-tutorial-building-a-blog-part-1\/ https:\/\/symfony.com\/doc\/current\/setup.html Install the latest Symfony 4 via\u00a0Composer\u00a0with the following command: composer create-project symfony\/website-skeleton blog teddy@teddy:~\/Documents\/works\/symfony4$ composer create-project symfony\/website-skeleton blog Installing symfony\/website-skeleton (v4.1.0) &#8211; Installing symfony\/website-skeleton (v4.1.0): Downloading (100%) Created project in blog Loading composer repositories with package information Updating dependencies (including require-dev) Package operations: 92 installs, 0 updates, 0 removals &#8211; Installing ocramius\/package-versions &hellip; <a href=\"https:\/\/myprojects.advchaweb.com\/index.php\/2018\/06\/25\/symfony-4-blog-app\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Symfony 4 &#8211; Blog App&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[33,79],"tags":[],"class_list":["post-2919","post","type-post","status-publish","format-standard","hentry","category-symfony","category-symfony-4"],"_links":{"self":[{"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/posts\/2919","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/comments?post=2919"}],"version-history":[{"count":15,"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/posts\/2919\/revisions"}],"predecessor-version":[{"id":2921,"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/posts\/2919\/revisions\/2921"}],"wp:attachment":[{"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/media?parent=2919"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/categories?post=2919"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/myprojects.advchaweb.com\/index.php\/wp-json\/wp\/v2\/tags?post=2919"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}