Wednesday, July 31, 2013
Tuesday, July 30, 2013
Friday, July 26, 2013
Escaping Zend_Form Error Element Labels in ZF1
Problem:
You have a form element label with extra characters (e.g. *, ", :, etc...) and you want to escape or remove it in the generated error message.
Example Zend Form Element:
Notice the setLabel() method string have characters "*" and ":"
These characters will show up in your error UL labels that are generated by Zend_Form_Decorator_FormErrors.
Solution:
In your controller when an error is generated...
This will override the default "htmlspecialchars" escaping of Zend_Form that is being used in the rendering of form elements.
You have a form element label with extra characters (e.g. *, ", :, etc...) and you want to escape or remove it in the generated error message.
Example Zend Form Element:
$firstName = new Zend_Form_Element_Text('first_name'); $firstName->class = "size_long"; $firstName->setLabel('* First Name:') ->setRequired(true) ->ddFilters(array('StringTrim', 'StripTags')) ->setDecorators(array( array('ViewHelper', array('helper' => 'formText')), array('Label', array('class' => 'label')), array('HtmlTag', array('tag' => 'div', 'class' => 'el_wrapper')), ));
Notice the setLabel() method string have characters "*" and ":"
These characters will show up in your error UL labels that are generated by Zend_Form_Decorator_FormErrors.
Solution:
In your controller when an error is generated...
// assume $form is an instance of Zend_Form if (!$form->isValid($_POST)) { $view = $form->getView(); $escape = function ($string) use ($view) { $string = htmlspecialchars($string, ENT_COMPAT, $view->getEncoding()); $string = str_replace(array('#', ':', '*'), '', $string); return trim($string); }; $view->setEscape($escape); }
This will override the default "htmlspecialchars" escaping of Zend_Form that is being used in the rendering of form elements.
Thursday, July 25, 2013
How ZF2's SharedEventManager Identifies Which Class to Listen to.
This is documented in the ZF2 official docs but I just want to save my thoughts while I was messing with the EventManager.
Problem: I was trying to grab an EventManager instance from 2 different modules.
Solution/Explanation:
The Zend\EventManager\EventManager class in ZF2 is not a singleton so EVERY module has its own instance of the EventManager. Therefore you cannot trigger events from other modules!
That is where the Zend\EventManager\SharedEventManager comes to the rescue although it itself is not a singleton you may ask but it is managed by Zend\EventManager\StaticEventManager which is one.
Confusion:
You may asked though how can the ShareEventManager find the event by just passing a string to attach() when the target trigger just reads like this:
Problem: I was trying to grab an EventManager instance from 2 different modules.
Solution/Explanation:
The Zend\EventManager\EventManager class in ZF2 is not a singleton so EVERY module has its own instance of the EventManager. Therefore you cannot trigger events from other modules!
That is where the Zend\EventManager\SharedEventManager comes to the rescue although it itself is not a singleton you may ask but it is managed by Zend\EventManager\StaticEventManager which is one.
Confusion:
// Listener $eventManager->getSharedManager()->attach('TriggerClass', 'shout', function ($e) { // do something });vs
// Listener $eventManager->attach('shout', function ($e) { // do something });Please notice the extra argument of attach() TriggerClass. That is how the Shared Event Manager can find which shout event to trigger.
You may asked though how can the ShareEventManager find the event by just passing a string to attach() when the target trigger just reads like this:
class TriggerClass { public function shout() { $this->eventManager->trigger('shout', $this, array('Hey you!')); // notice i am NOT attaching to the SharedEventManager } }Sure it maps it using the same classname (although it does not matter) named TriggerClass but what if I want to use a different id like this one below to my listener and still want to trigger the same event?
// Listener $eventManager->getSharedManager()->attach('Blah', 'shout', function ($e) { // do something });This is where the setIdentifiers() comes in. Back when implementing the setEventManager() of EventManagerInterface set the identifiers like below:
public function setEventManager(EventManager\EventManagerInterface $events) { $events->setIdentifiers(array( 'Blah' )); $this->events = $events; return $this; }Now you can have a listener:
$this->getEventManager()->getSharedManager()->attach('Blah' ,'shout', function ($e) { var_dump($e->getParams()); var_dump($e->getTarget()); });That is how the SharedEventManager maps out which Event to trigger.
Tuesday, July 23, 2013
Creating A Project in Composer Using a Specific Version
You want to use a specific 2.3.* develop version found in:
https://packagist.org/packages/zendframework/zendframework
You would do:
php composer.phar create-project zendframework/zendframework=2.3.x-dev /your/path/
or
php composer.phar create-project zendframework/zendframework /your/path/ 2.3.x-dev
Or you want to just use the develop branch:
php composer.phar create-project zendframework/zendframework /your/path/ dev-develop
Warning: beware of this method though. If the package author changes version and they do explicit branching, when you do composer update your update will fail! Further reading to fix this problem through branch aliasing (https://igor.io/2013/01/07/composer-versioning.html)
Reference:
https://github.com/composer/composer/issues/957
http://getcomposer.org/doc/03-cli.md#create-project
https://packagist.org/packages/zendframework/zendframework
You would do:
php composer.phar create-project zendframework/zendframework=2.3.x-dev /your/path/
or
php composer.phar create-project zendframework/zendframework /your/path/ 2.3.x-dev
Or you want to just use the develop branch:
php composer.phar create-project zendframework/zendframework /your/path/ dev-develop
Warning: beware of this method though. If the package author changes version and they do explicit branching, when you do composer update your update will fail! Further reading to fix this problem through branch aliasing (https://igor.io/2013/01/07/composer-versioning.html)
Reference:
https://github.com/composer/composer/issues/957
http://getcomposer.org/doc/03-cli.md#create-project
Monday, July 22, 2013
Overriding the ZF1 Zend_Form Validator's setRequired message
The Zend_Form_Element's isRequired() method uses the Zend_Validate_NotEmpty validator under the hood and thus uses its message template for outputs.
For simple Zend_Form_Element_Text override you can just do this:
For Multi elements though, you need to set the NotEmpty's breakChainOnFailure to true as below:
For simple Zend_Form_Element_Text override you can just do this:
$e = new Zend_Form_Element_Text('text_element'); $e->setRequired(true) // needs to be true ->addValidators(array('NotEmpty')); // needs to be explicitly set $e->getValidator('NotEmpty') ->setMessage( 'This is my new message that you entered an empty string!', Zend_Validate_NotEmpty::IS_EMPTY );
For Multi elements though, you need to set the NotEmpty's breakChainOnFailure to true as below:
$e = new Zend_Form_Element_MultiCheckbox('text_element'); $e->setRequired(true); // needs to be true ->addValidators(array( array('NotEmpty', true) // notice "true" is set for breakChain option )); $e->getValidator('NotEmpty') ->setMessage( 'This is my new message that you entered an empty string!', Zend_Validate_NotEmpty::IS_EMPTY );
Friday, July 12, 2013
Using An Existing Method on a Mocked Object
Problem: You want to use an existing method in a class for unit testing in a mocked object but cannot use it because the method is returning an error when called.
Example:
Unit test:
Solution:
For the curious, what will happen if you pass an empty array:
You shouldnt really do this at all because you can just instantiate class A after but its just a good thing to know!
Example:
class A { public function methodA() { return "Hello"; } }
Unit test:
$mock = $this->getMockBuilder('A') ->getMock(); $mock->methodA(); // returns an error
Solution:
$mock = $this->getMockBuilder('A') ->setMethod(null) // the trick is explicitly using a null ->getMock(); $mock->methodA(); // returns "Hello"
For the curious, what will happen if you pass an empty array:
$mock = $this->getMockBuilder('A') ->setMethod(array()) ->getMock(); $mock->methodA(); // returns null
You shouldnt really do this at all because you can just instantiate class A after but its just a good thing to know!
Friday, July 5, 2013
JQuery UI Model with submit form on confirm
I was having frustrating problem using jquery's submit button inside a Jquery ui modal box when a user submit. the problem occurs when you explicitly set the submit() to return false that you cannot do anything after it even explicitly saying submit(function (){return true;})
http://www.jensbits.com/2009/08/10/modal-confirmation-dialog-on-form-submit-javascript-jquery-ui-and-thickbox-varieties/
solution is to NOT use the submit function at all after confirm:
http://www.jensbits.com/2009/08/10/modal-confirmation-dialog-on-form-submit-javascript-jquery-ui-and-thickbox-varieties/
solution is to NOT use the submit function at all after confirm:
$( "#dialog-confirm" ).dialog({ resizable: false, autoOpen: false, height: 140, modal: true, buttons: { "Delete pendings": function() { document.scheduled_release_form.submit(); }, Cancel: function() { $( this ).dialog("close"); } } });
<form action="" method="post" name="scheduled_release_form" id="scheduled_release_form">
<input type="button" name="submit_update" value="submit update" id="submit_update"><input type="button" name="submit_delete" value="delete pendings" id="submit_delete">
</form>
Mac vagrant port forwarding
Just reposting this blog for reference.
http://www.dmuth.org/node/1404/web-development-port-80-and-443-vagrant
If you have a vagrant instance that is running on 8080 for web services and you want to forward 80 traffic to it so you will not be appending ports to your url like http://localhost:8080 but instead just use http://localhost do the following bellow:
http://www.dmuth.org/node/1404/web-development-port-80-and-443-vagrant
If you have a vagrant instance that is running on 8080 for web services and you want to forward 80 traffic to it so you will not be appending ports to your url like http://localhost:8080 but instead just use http://localhost do the following bellow:
sudo
ipfw add 100 fwd 127.0.0.1,8080 tcp from any to me 80
sudo
ipfw add 101 fwd 127.0.0.1,8443 tcp from any to me 443
Tuesday, July 2, 2013
Subscribe to:
Posts (Atom)