...

Hi! I’m Starx

experienced Software Developer. And this is my blog
Start Reading About me
Blog Page
March 28, 2016

listen to kernel.request event on Silex?

Lhassan Baazzi’s Question:

I want to listen to kernel.request event on Silex microframework http://silex.sensiolabs.org/documentation

How ?

You can access the dispatcher service as $app['dispatcher'] and you can see here how to use it. But I think you should use Silex’s before event instead as it’s called on kernel.request as well (here is a good expample how to use it).

UPDATE:

The links above are outdated. Before filters moved to a new middlewares section and here is how you can write one:

$app->before(function (Request $request) {
    // do what you want ...

    // if you want you can return a response so the controller won't be called
    // return new Response($content);

    // or just return null
});

There is a on($eventName, $callback, $priority = 0) method on silex application which you can use to listen to any event. On this particular case it will be as following.

$app->on(SymfonyComponentHttpKernelKernelEvents::REQUEST, function (SymfonyComponentHttpKernelEventGetResponseEvent $event) use ($app) {
    // Your actions
});
Read more
March 18, 2016

Symfony2 form collection not calling addxxx and removexxx even if 'by_reference' => false

Nick Denry’s Question:

I have the Customer entity and two one-to-many relations CustomerPhone and CustomerAddress.

The Customer entity has addPhone/removePhone and addAddress/removeAddress “adders”.

CustomerType collections options has ‘by_reference’ => false for both collections.

Entity functions addPhone/removePhone and addAddress/removeAddress not called after form submitted, so CustomerPhone and CustomerAddress have no parent id after persist.

Why could addPhone/removePhone and addAddress/removeAddress not called on form submit?

UPD 1.

After @Baig suggestion now I have addPhone/removePhone “adders” called, but addAddress/removeAddress not. Can’t get why because they are identical.

 # TestCustomerBundle/Entity/Customer.php

 /**
 * @var string
 *
 * @ORMOneToMany(targetEntity="CustomerPhone", mappedBy="customerId", cascade={"persist"}, orphanRemoval=true)
 */
private $phone;

/**
 * @var string
 *
 * @ORMOneToMany(targetEntity="CustomerAddress", mappedBy="customerId", cascade={"persist"}, orphanRemoval=true)
 */
private $address;

Same file “adders”

# TestCustomerBundle/Entity/Customer.php
/**
 * Add customer phone.
 *
 * @param Phone $phone
 */
public function addPhone(CustomerPhone $phone) {
    $phone->setCustomerId($this);
    $this->phone->add($phone);

    return $this;
}

/**
 * Remove customer phone.
 *
 * @param Phone $phone customer phone
 */
public function removePhone(CustomerPhone $phone) {
    $this->phone->remove($phone);
}
/**
 * Add customer address.
 *
 * @param Address $address
 */
public function addAddress(CustomerAddress $address) {
    $address->setCustomerId($this);
    $this->address->add($address);

    return $this;
}

/**
 * Remove customer address.
 *
 * @param Address $address customer address
 */
public function removeAddress(CustomerAddress $address) {
    $this->address->remove($address);
}

Relations:

# TestCustomerBundle/Entity/CustomerPhone.php
/**
 * @ORMManyToOne(targetEntity="Customer", inversedBy="phone")
 * @ORMJoinColumn(name="customer_id", referencedColumnName="id")
 **/
private $customerId;

#TestCustomerBundle/Entity/CustomerAddress.php
/**
 * @ORMManyToOne(targetEntity="Customer", inversedBy="address")
 * @ORMJoinColumn(name="customer_id", referencedColumnName="id")
 **/
private $customerId;

CustomerType form:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name')
        ->add('phone', 'collection', array(
            'type' => new CustomerPhoneType(),
            'allow_add' => true,
            'allow_delete' => true,
            'by_reference' => false,
            'options' => array('label' => false)
        ))
        ->add('address', 'collection', array(
            'type' => new CustomerAddressType(),
            'allow_add' => true,
            'allow_delete' => true,
            'by_reference' => false,
            'options' => array('label' => false)
        ))
        ->add('submit', 'submit')
    ;
}

Controller.

# TestCustomerBundle/Controller/DefaultController.php

public function newAction(Request $request)
    {
        $customer = new Customer();
        // Create form.
        $form = $this->createForm(new CustomerType(), $customer);
        // Handle form to store customer obect with doctrine.
        if ($request->getMethod() == 'POST')
        {
            $form->bind($request);
            if ($form->isValid())
            {
                /*$em = $this->get('doctrine')->getEntityManager();
                $em->persist($customer);
                $em->flush();*/
                $request->getSession()->getFlashBag()->add('success', 'New customer added');
            }
        }
        // Display form.
        return $this->render('DeliveryCrmBundle:Default:customer_form.html.twig', array(
            'form' => $form->createView()
        ));
    }

UPD 2.
Test if addAddress called.

/**
     * Add customer address.
     *
     * @param Address $address
     */
    public function addAddress(Address $address) {
        jkkh; // Test for error if method called. Nothing throws.
        $address->setCustomerId($this);
        $this->address->add($address);        
    }

UPD 3.

CustomerAddressType.php

<?php

namespace DeliveryCrmBundleForm;

use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolverInterface;

class CustomerAddressType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('street')
            ->add('house')
            ->add('building', 'text', ['required' => false])
            ->add('flat', 'text', ['required' => false])
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'DeliveryCrmBundleEntityCustomerAddress'
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'delivery_crmbundle_customeraddress';
    }
}

CustomerPhoneType.php

<?php

namespace DeliveryCrmBundleForm;

use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolverInterface;

class CustomerPhoneType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('number')
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'DeliveryCrmBundleEntityCustomerPhone'
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'phone';
    }
}

This answer corresponds to Symfony 3, but I am sure this applies to Symfony 2 as well. Also this answer is more as a reference than addressing OP’s issue in particular (which I am not to clear)

On ..Symfony/Component/PropertyAccess/PropertyAccessor.php the method writeProperty is responsible for calling either setXXXXs or addXXX & removeXXXX methods.

So here is order on which it looks for the method:

  1. If the entity is array or instance of Traversable (which ArrayCollection is) then pair of

    • addEntityNameSingular()
    • removeEntityNameSingular()

      Source for reference:

      if (is_array($value) || $value instanceof Traversable) {
          $methods = $this->findAdderAndRemover($reflClass, $singulars);
      
          if (null !== $methods) {
              $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_ADDER_AND_REMOVER;
              $access[self::ACCESS_ADDER] = $methods[0];
              $access[self::ACCESS_REMOVER] = $methods[1];
          }
      }
      
  2. If not then:

    1. setEntityName()
    2. entityName()
    3. __set()
    4. $entity_name (Should be public)
    5. __call()

      Source for reference:

      if (!isset($access[self::ACCESS_TYPE])) {
          $setter = 'set'.$camelized;
          $getsetter = lcfirst($camelized); // jQuery style, e.g. read: last(), write: last($item)
      
          if ($this->isMethodAccessible($reflClass, $setter, 1)) {
              $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_METHOD;
              $access[self::ACCESS_NAME] = $setter;
          } elseif ($this->isMethodAccessible($reflClass, $getsetter, 1)) {
              $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_METHOD;
              $access[self::ACCESS_NAME] = $getsetter;
          } elseif ($this->isMethodAccessible($reflClass, '__set', 2)) {
              $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_PROPERTY;
              $access[self::ACCESS_NAME] = $property;
          } elseif ($access[self::ACCESS_HAS_PROPERTY] && $reflClass->getProperty($property)->isPublic()) {
              $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_PROPERTY;
              $access[self::ACCESS_NAME] = $property;
          } elseif ($this->magicCall && $this->isMethodAccessible($reflClass, '__call', 2)) {
              // we call the getter and hope the __call do the job
              $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_MAGIC;
              $access[self::ACCESS_NAME] = $setter;
          } else {
              $access[self::ACCESS_TYPE] = self::ACCESS_TYPE_NOT_FOUND;
              $access[self::ACCESS_NAME] = sprintf(
                  'Neither the property "%s" nor one of the methods %s"%s()", "%s()", '.
                  '"__set()" or "__call()" exist and have public access in class "%s".',
                  $property,
                  implode('', array_map(function ($singular) {
                      return '"add'.$singular.'()"/"remove'.$singular.'()", ';
                  }, $singulars)),
                  $setter,
                  $getsetter,
                  $reflClass->name
              );
          }
      }
      

To answer OP’s issue, based on the above mentioned information, the PropertyAccessor class of symfony is not able to read your addXX and removeXX method properly. The potential reason might be that is not identified as array or ArrayCollection which has to be done from the constructor of the entity

public function __construct() {
     $this->address = new ArrayCollection();
     // ....
}
Read more
March 4, 2016

JS/HTML – onresize doesn't fire

LastSecondsToLive’s Question:

I wanted to add the resize event to an element (I know you can’t add resize to a specific element, but it would be fine if the JS-function would be triggered on a resize of any kind – not the specific element).

I was thinking about this:

<div onresize="wrapperResize();"></div>

This somehow doesn’t work (Safari user here). This however works:

<div onclick="wrapperResize();"></div>

Currently wrapperResize() only holds a simple console.log(). What could I do about this?

PS: This works great (traditional checked), what do I even do different?

EXTRA: The div has a fixed height and 33% of the body element wide. Even though the event should fire, when the window is resized I thought this may be the cause.

I think you should set onresize handler on window and do it in javascript, not inline html.. Like so

window.onresize = yourFunction

You cannot attach a onresize event on a <div> container. It is only available for window for most of the browsers.

Read more
February 8, 2016

Appending div to iframe

Jesus Christ’s Question:

What is wrong with this piece of code:

jQuery('<iframe id="groundplan_popup" class="groundplan_hidden" />').appendTo("#popup_holder");
var iframe = jQuery("#groundplan_popup");
iframe.attr("src","::censored::" + filename);
var iframe_body = iframe.contents().find('body').append('<div id="groundplan_popup_exit"></div>');
var exit_btn_gp = iframe_body.append(jQuery("#groundplan_popup_exit"));

So i have to dynamically create an iframe element which will open up .pdf file in a popup and that part works. What I can’t manage to do is create a div with an id of “groundplan_popup_exit” within that iframe. I don’t know exactly why this doesnt’ work and what exactly I’m doing wrong. When i inspect the iframe window console brings out this warning:

/deep/ combinator is deprecated. See https://www.chromestatus.com/features/6750456638341120 for more
details.

Dont know if it has anything to do with the reason why this isn’t working.

EDIT:

This is what my code looks like now.
enter image description here

Console prtscr:
enter image description here

Iframe console elements prtscr:

enter image description here

So i’m basically confused about the whole situation as I’m not that experienced in using jquery in general and this is my first time using it with iframes. I’m not even sure if the #groundplan_popup_exit div is even created and how do I find it if it is.

I see some problems:

var iframe_body = iframe.contents().find('body').append('<div id="groundplan_popup_exit"></div>');

Here you are already appending the element to the body.

var exit_btn_gp = iframe_body.append(jQuery("#groundplan_popup_exit"));

After you have appended above, you are trying to append again with jQuery("#groundplan_popup_exit") which does not even exists.

Fix (untested) would be something like this:

var iframe_body = iframe.contents().find('body');
var exit_btn_gp = iframe_body.append('<div id="groundplan_popup_exit"></div>');
Read more
December 4, 2015

How to know if a page loaded via iframe is within sandbox?

Layke’s Question:

I’m trying to detect if a page is loaded via a sandboxed iframe. Is this possible?

For example,we provide custom embeddable widgets and some people think they are being smart by sandboxing them in their iframe, but this breaks certain things.. such as window.top.location

Obviously, they could enable the features we need, but ideally, I should be able to just do something like:

"sandbox" in window.top

I have also tried doing

try {
    // do something that would not work if within sandbox
} catch(e) {

}

But this doesn’t work because it’s a browser security error, and not related to javascript.

JSFiddle actually sandbox their iframes to prevent window.top.location navigation, so this would be a good example to show you.
If you look at this example here:

http://jsfiddle.net/mwsb8geL/show/

You can see the error when you press the Instant Book Online button.

enter image description here

A project sandblaster can help you detect if you running being sandboxed.

Inside the iframe where you are testing if it is sandbox, open up your script tag and paste the contents of https://raw.githubusercontent.com/JamesMGreene/sandblaster/master/dist/sandblaster.js. This is due to the security issue.

After this, its as simple as the following.

var result = sandblaster.detect();
if(result.sandboxed === true) {
    //sandboxed
}

Here is a demo I made for another answer but shows that the solution works.

Read more

Detect if JavaScript is Executing In a Sandboxed Iframe?

Omninternet’s Question:

I have a product that’s playing a video in Flash (if available), and falls back to HTML5 if Flash isn’t available.

I’m not able to find a way to determine if JavaScript is executing within an Iframe with the “sandbox” attribute, which is necessary for my solution because sandboxed iframes disable all plugins. The sandboxed iframe could be as simple as this:

<iframe src="http://www.cross-domain.com/" sandbox="allow-scripts">

To determine if Flash is enabled, I’m using swfobject’s method of checking navigator.plugins[“Shockwave Flash”].description, which is set even when in a sandboxed iframe. I can load the swf object, but it doesn’t play.

To reproduce this issue, visit http://jsfiddle.net/max_winderbaum/9cqkjo45/, open your chrome inspector and click “Run”. The script on the cross-domain site will pause in the context of the sandboxed iframe.

According to the W3 spec at http://dev.w3.org/html5/spec-preview/browsers.html#sandboxing-flag-set, there is supposed to be an “active sandboxing flag set” on the document that JavaScript can access (at least that’s how I’m reading the spec). There doesn’t seem to be any flag set on the iframe’s document.

Does anyone have any ideas / solutions on how to detect if JavaScript is executing from within a sandboxed iframe?

A project sandblaster can help you detect if you running being sandboxed.

Sandbox check if itself is framed first and then scans through the attributes of the frame element to detect several information about itself. These includes framed, crossOrigin, sandboxed, sandboxAllowances, unsandboxable, resandboxable, sandboxable.

To detect if itself is sandboxed in our case, it checks if the frame element has an attribute sandbox.

// On below `frameEl` is the detected frame element
try {
  result.sandboxed = frameEl.hasAttribute("sandbox");
}
catch (sandboxErr) {
  result.sandboxed = null;
  if (typeof errback === "function") {
    errback(sandboxErr);
  }
}

I tried to replicate your issue and to test if this solution works, I had to paste the script into the window itself due to the security issue.

<html>
    <head>
    </head>
    <body>

    <script>
        //Paste the contents of the script(https://raw.githubusercontent.com/JamesMGreene/sandblaster/master/dist/sandblaster.js) here

        var result = sandblaster.detect();
        if(result.sandboxed === true) {
            //sandboxed
        }
        debugger;
    </script>
    </body>
</html>

Here is a demo: http://jsfiddle.net/Starx/tzmn4088/ that shows this working.

Read more
December 2, 2015

Count Rows in Doctrine QueryBuilder

Acyra’s Question:

I’m using Doctrine’s QueryBuilder to build a query, and I want to get the total count of results from the query.

$repository = $em->getRepository('FooBundle:Foo');

$qb = $repository->createQueryBuilder('n')
        ->where('n.bar = :bar')
        ->setParameter('bar', $bar);

$query = $qb->getQuery();

//this doesn't work
$totalrows = $query->getResult()->count();

I just want to run a count on this query to get the total rows, but not return the actual results. (After this count query, I’m going to further modify the query with maxResults for pagination.)

Something like:

$qb = $entityManager->createQueryBuilder();
$qb->select('count(account.id)');
$qb->from('ZaysoCoreBundle:Account','account');

$count = $qb->getQuery()->getSingleScalarResult();

For people who are using only Doctrine DBAL and not the Doctrine ORM, they will not be able to access the getQuery() method because it doesn’t exists. They need to do something like the following.

$qb = new QueryBuilder($conn);
$count = $qb->select("count(id)")->from($tableName)->execute()->fetchColumn(0);
Read more
October 29, 2015

Add Icon between each Div

Michaelmcgurk’s Question:

I have a very simple page on my site: http://jsfiddle.net/95sptas0/

Using only CSS, how do I add an icon between each .post div? I’d like one after each .post div except the last. I’m hoping to use this icon: http://fortawesome.github.io/Font-Awesome/icon/arrow-down/

.post {
    margin-bottom:50px;
    background:#eaeaea
}
<div class="post">
    <h1>This is a Post</h1>
</div>

<div class="post">
    <h1>This is a Post</h1>
</div>

<div class="post">
    <h1>This is a Post</h1>
</div>  

After including the “FontAwesome” font, the following CSS might do it:

.post::after { 
    content: "f063";
    font-family:'FontAwesome';
}

f063 is the code for the “down arrow” using the FontAwesome font.

In order for you to apply this to every element except your last, you can use the last-of-type selector:

.post:last-of-type::after { 
    display: none;
}

The font awesome icons requires to have an element with defined class. In you case this is <i class="fa fa-arrow-down"></i>. Since this is a new element you cannot use CSS to handle DOM manipulation.

If you can opt for text based unicode icons and font-based icons however, it will be possible through adjacent selector.

.post+.post::before {
    content: "↓";
}

Demo: http://jsfiddle.net/95sptas0/4/

Read more
October 14, 2015

Select2 drop-down for countries, with flags

Delavnog’s Question:

Does somebody have an easy to use example of a country drop-down, with country flags, for Select2? I am about to implement one based on this suggestion, but I would prefer to avoid reinventing the wheel.

I was working on a similar problem and here is how I solve it.

(function($) {
    $(function() {
        var isoCountries = [
            { id: 'AF', text: 'Afghanistan'},
            ...
        ];
        //Assuming you have a select element with name country
        // e.g. <select name="name"></select>

        $("[name='country']").select2({
            placeholder: "Select a country",
            data: isoCountries
        });
    });
})(jQuery);

I also have made a gist about it and following are the demos.

Read more
September 1, 2015

How to make a multiline cursor without using a mouse in Sublime text 3?

Ivan’s Question:

The only way to make a multiline cursor in Sublime text 3 is Ctrl+Shift+RC+Drag. Is there any way to do this without using a mouse?

Yes, there is. Using Shift or Shift, select the lines you want multiple cursors on. Next, hit CtrlShiftL to split the selection into lines. Finally, hitting will put the cursors at the beginning of the lines, while will put them at the end.

Edit

There is also another, quicker way (thanks to minitech) – CtrlAlt/ will create multiple cursors without having to do selections first, and you can place the cursors anywhere in the line you wish. However, on Windows these key combos may be mapped to changing the screen orientation. To change this, hit CtrlAltF12 to open the Intel control panel, click Options, and either remap the screen orientation hotkeys, or click Off on the left side to disable all of them.

You can use Middle mouse button for this as well.

Click & Hold Middle mouse button and drag up and down

Read more
...

Please fill the form - I will response as fast as I can!