Nov06
Tagged in:Comments:
Recently I have been deploying PHP service on a google cloud run and I have encountered a 503 service unavailable error.
Problem
On the first execution, there is a 503 error, however, any other request after the first one works fine.
Solution
After investigation, I have seen that if you are using an image from “webdevops/php-apache” then you will see this error.
I have replaced the image with the original version “php:7.4-apache”
This has resolved the issue and I do not see the initial 503 errors anymore.
Apr12
Tagged in:sonata, sonata-admin, sonataAdminBundle, symfony, symfony2Comments:
Post (parent) to display comments (child) list.
Creating list of rows on sonata admin bundle is fairly easily with there documentation. But when you want to go bit advance on creating sub list of parent entity, then you would be scratching your head. Luckily this post will help you overcome this very easily.
Assuming you already have PostAdmin and CommentAdmin class to display list individually, if you don’t then please create them first.
We will tell our child class, who is his father (parent).
// .. YourBundle/Admin/CommentAdmin.php
class CommentAdmin extends Admin
{
protected $parentAssociationMapping = 'post';
...
}
Now we can create services for parent and child, if you already have created the services, then please make sure you add call method on parent service.
// .. service.yml
admin.comment:
class: Sonata\YourBundle\Admin\CommentAdmin
arguments: [~, Sonata\YourBundle\Entity\Comment,~]
tags:
- {name: sonata.admin, manager_type: orm, group: "Content"}
admin.post:
class: Sonata\YourBundle\Admin\PostAdmin
arguments: [~, Sonata\YourBundle\Entity\Post, ~]
tags:
- {name: sonata.admin, manager_type: orm, group: "Content"}
calls:
- [addChild, ['@admin.comment']]
That’s it!
We can now add links on post list page, but you can add link on any page as you like.
Create template to add link
// ..YourBundle/Resources/views/CRUD/post_comments.html.twig
<a class="btn btn-sm btn-default" href="{{ path('OUR_NEW_CHILD_ROUTE_ID', {'id': object.id }) }}">Comments</a>
Replace OUR_NEW_CHILD_ROUTE_ID with comment list route id, which you can find it with following command line.
$ php app/console debug:route
Now we are ready to add link on post list page for each post.
// ..YourBundle/Admin/PostAdmin.php
class PostAdmin extends Admin
{
protected function configureListFields(ListMapper $listMapper)
{
$listMapper->add('_action', 'actions', array(
'actions' => array(
'show' => array(),
'edit' => array(),
'comments' => array('template' => 'YourBundle:CRUD:post_comments.html.twig')
)
))
}
}
That’s it you are done. Now all post are linked properly with its child comments as oneToMany relationship.
SonataAdminBundle has so much more to offer, which can be hidden if you are new to it, but once you learn it. Then creating admin area would take you few days or less then week depending on the size of your application.
Feb16
Tagged in:Comments:
Simply use angular2 pipe slice by appending at the end of array.
<li *ngFor="#user of users | slice:1">
{{ user.name }} is {{ user.age }} years old.
</li>
Feb02
Tagged in:bundle, symfony, symfony2, symfony3, upgrade, upgradingComments:
Everyone is excited about Symfony 3, including myself 🙂
Symfony 3 or Symfony 2?
Symfony 2.8 is exactly same as Symfony 3. But wait, then what’s the difference?
Symfony 3 mostly have new directory structure for logs, cache and console. Also all the previous deprecated functions are removed.
Should I upgrade then, if its same?
No!!!, Even tho it is exactly same, but knowing all the deprecated functions are removed on Symfony 3, you should ask yourself.
Are you going to be using third party bundles?
and thous bundles are update-to-date with Symfony 3. Most likely you will get the answer no.
having third party bundles on Symfony 3 will break your application, If it was using any of the deprecated function.
Soon we can upgrade when everyone upgrades their bundles.
Updated – Wed 17 Feb
You can also check your vendor packages, if they are using any old deprecated functions, check following link for more details – http://symfony.com/blog/paving-the-way-for-symfony-3-with-the-deprecation-detector-tool
Complete list of changes
Jan31
Tagged in:auto wiring, dependency injection, example, how to, services, symfonyComments:
Previously if you ever had dependency for your object, you had to make sure the names for dependency services are correctly passed down to your new service before you can start using it.
Since Symfony 2.8 which is official exact version of Symfony 3 (removing all the deprecated functions).
Now you can create services without worrying about dependency injection services with auto wiring feature. The key feature in auto wiring is, if one of your dependency injection service does not exist, then it will auto create it and inject it.
Let’s assume we have following object, which needs to be created as service.
namespace AppBundle\Service;
use AppBundle\Service\House;
class Room
{
private $house;
public function __construct(House $house)
{
$this->house = $house;
}
}
Old way creating service
services:
house:
class: AppBundle\Service\House
room:
class: AppBundle\Service\Room
arguments:
- @house
New way with auto wiring
services:
room:
class: AppBundle\Service\Room
autowire: true
The above example is very simple. Now imagine you have 5 or even 6 different dependency injections, you would have to waste time on getting each dependency service names and on top, if you later on decided to change the or remove dependency from your object, then you have to update services as well. With auto wiring you don’t have to worry about anything, it worries for you.
What about Performance?
It is exactly as same as before. Compiler builds and save everything in cache, just like before.
Jan28
Tagged in:Comments:
Remove form type name from the form
Sometimes we need to integrate third party application or form, which requires us to remove any array type form names.
Problem
Normal form will create FormTypeName[fieldName]
<input type="text" value="" name="formTypeName[fieldName]">
Our final outcome should look like field name only without any form type name.
<input type="text" value="" name="fieldName">
Solution
Create the form using createNamed method.
$form = $this->get('form.factory')->createNamed(null, new MyFormType(), $dataObject, $formOptions);
When you pass first argument as null, it will remove form type name and make fields as field name only.
Solution 2
You can also change your formType and return blockPrefix null.
class MyFormType extends AbstractType
{
...
/**
* This will remove formTypeName from the form
* @return null
*/
public function getBlockPrefix() {
return null;
}
}
I recommend first solution.
Jan28
Tagged in:Comments:
It’s 2016, you can use trait which will help you extend same class with multiple libraries.
I keep seeing container class get extended into another class, which then extends to another, before you know it you have extended 5 different classes just to use libraries.
What if you can include 5 different libraries into 1 object without extending? Well you can use it with php5.4 trait feature.
Container dependency injection trait class
namespace iBasit\ToolsBundle\Utils\Lib;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Symfony\Component\DependencyInjection\ContainerInterface;
trait Container
{
private $container;
public function setContainer (ContainerInterface $container)
{
$this->container = $container;
}
/**
* Shortcut to return the Doctrine Registry service.
*
* @return Registry
*
* @throws \LogicException If DoctrineBundle is not available
*/
protected function getDoctrine()
{
if (!$this->container->has('doctrine')) {
throw new \LogicException('The DoctrineBundle is not registered in your application.');
}
return $this->container->get('doctrine');
}
/**
* Get a user from the Security Token Storage.
*
* @return mixed
*
* @throws \LogicException If SecurityBundle is not available
*
* @see TokenInterface::getUser()
*/
protected function getUser()
{
if (!$this->container->has('security.token_storage')) {
throw new \LogicException('The SecurityBundle is not registered in your application.');
}
if (null === $token = $this->container->get('security.token_storage')->getToken()) {
return;
}
if (!is_object($user = $token->getUser())) {
// e.g. anonymous authentication
return;
}
return $user;
}
/**
* Returns true if the service id is defined.
*
* @param string $id The service id
*
* @return bool true if the service id is defined, false otherwise
*/
protected function has ($id)
{
return $this->container->has($id);
}
/**
* Gets a container service by its id.
*
* @param string $id The service id
*
* @return object The service
*/
protected function get ($id)
{
if ('request' === $id)
{
@trigger_error('The "request" service is deprecated and will be removed in 3.0. Add a typehint for Symfony\\Component\\HttpFoundation\\Request to your controller parameters to retrieve the request instead.', E_USER_DEPRECATED);
}
return $this->container->get($id);
}
/**
* Gets a container configuration parameter by its name.
*
* @param string $name The parameter name
*
* @return mixed
*/
protected function getParameter ($name)
{
return $this->container->getParameter($name);
}
}
Your custom object, which will be service.
namespace AppBundle\Utils;
use iBasit\ToolsBundle\Utils\Lib\Container;
class myObject
{
use Container;
}
Your object service settings
myObject:
class: AppBundle\Utils\myObject
calls:
- [setContainer, ["@service_container"]]
Call your service in controller
$myObject = $this->get('myObject');
Jul11
Tagged in:Comments:
Mailgun Setup
- Create a Mailgun account
- Add your domain name (no www)
domain.com
- Keep the page open and open a new tab to CloudFlare
Cloudflare
- Choose your site and select
DNS Settings
- Add the two
Text
records
- Add the
CNAME
record
- Make sure the cloudflare cloud is gray and not orange/active
- Add the two
MX
records
- Name
domain.com
(no www)
- Mail handled by
mxa.mailgun.org
or mxb.mailgun.org
Back at Mailgun
- Click
add
- Click
Check DNS Records Now
- It’ll tell you once it detects the updated DNS records
Email Forwarding
- From Mailgun, choose
Routes
Create Your First Route
- Priority 10
- Filter Expression This is where you list the email address you want to forward to gmail
match_recipient("you@domain.com")
- Actions This is the gmail address you want to receive your mail
forward("me@gmail.com")
- Description Name it something so you remember what it’s for
Use Gmail to send mail from your domain
- Log in to Gmail and go to
settings
- Go to
Accounts and Import
- Go to
Send mail as
and select add another email you own
- name: Anything you want
- email address: name@domain.com (this should be the email you set up in the steps before)
- Leave
treat as an alias
checked
- Click
Next Step
- For the following info you’ll need to login to mailgun and use the info under
Domain Information
- SMTP Server Use
SMTP Hostname
from Mailgun
- Username Use
Default SMTP Login
from Mailgun
- Password Use
Default Password
from Mailgun
- Leave
Secured connection using TLS
selected
- Click add account
- Once it’s verified you should be able to compose emails and list your new email in the
from
line so nobody needs to know it’s coming from your personal gmail account.
Jan05
Tagged in:environment, git, github, github.com, Php, project, respository, serverComments:
We will cover UAT and Live environments and exclude developer environment.
DEV environment for developer to code and test, before he push his commits to remote repository (github.com), which will be auto deploy to UAT environment for everyone to test with other developers changes. Note – we wont be covering DEV environment.
UAT environment for testing the site and getting ready to push to live environment after we think all the bugs are fixed.
Live environment to have the latest version of the website.
(more…)
Jan04
Tagged in:code, fix, html, parsing, Php, wordpressComments:
It’s really annoying and waste loads of hours trying to fix how can one show example of php code, while still use visual editor for quick snapshots or fancy tools of tinyMCE and able to show color coding examples using google prettify.
(more…)
Older posts