Get Cakephp 3 display true/false for booleans - php

Using cakephp 3, I have a boolean [tinyint(1)] in a table, and the edit and add templates have a check box on the form, but how do I get the index and view templates to display a string like true/false or yes/no instead of 1/0. Do I map them over in the controller actions, or is there a option I can add to the templates?

The answers given both work fine.
I created a Helper class in /src/View/Helper/FormatBooleanHelper.php as below:
<?php
/*
* FormatBooleanHelper
*
* CakePHP Helper created to format boolean values in either Yes/No or True/False text.
* By: Jared Testa
*
*/
namespace App\View\Helper;
use Cake\View\Helper;
class FormatBooleanHelper extends Helper
{
/**
* yesNo method
*
* #param boolean| $value boolean
* #return string
*
*/
public function yesNo($value, $showNo = true) {
return ($value) ? "Yes" : (($showNo) ? "No" : "");
}
/**
* trueFalse method
*
* #param boolean| $value boolean
* #return string
*
*/
public function trueFalse($value, $showFalse = true) {
return ($value) ? "True" : (($showFalse) ? "False" : "");
}
}
?>
The helper is used in the standard convention by including $this->loadHelper('FormatBoolean'); in your initialize method in the AppView.php file.
You then use the Helper in your view by including $this->FormatBoolean->yesNo($booleanVariable) or $this->FormatBoolean->yesNo($booleanVariable, false) in your view. The latter example will leave the field blank in a false response.
Overkill? Perhaps...but I think it fits into the CakePHP structure, and it was a good exercise in creating your own helper.
I'm using the helper in CakePHP version 3.3.4. Hope this helps someone in the future.

simply:
<?= ($var)?'yes':'no' ?>

When you go in to display the data you can choose to display a string instead of the int. This is a simplified approach since you didn't provide any code or other information:
In the view, $isTrue being the boolean:
<?php if($isTrue){echo "true";}else{echo "false";} ?>

I added (for bottom, jtesta answer) method to get graphically representation - "check" or "x" using Foundation Icon Fonts 3:
public function checkX($value, $showFalse = true) {
return ($value) ? '<i class="fi-check"></i>' : (($showFalse) ? '<i class="fi-x"></i>' : '');
}
Image how it loks like

Related

How deserialize from array ids in jms?

I can not figure out how to deserialize a object from a array of IDs? Here is a simple example my array.
"roles":["1","2","3"]
But when trying I get the error that object expected-class AppBundle\Entity\Role... is There something for this? Thank you all for your attention!
The problem is the one mentioned by LBA in his answer. Basically in order for jms serializer to create an object, it need to be provided with an Array. The solution if you are ok with changing the structure of the api is also good.
I'm assuming your $role jms configuration looks something like this
/**
* #var ArrayCollection
*
* #JMS\Expose
* #JMS\Accessor(setter="setRoles")
* #JMS\SerializedName("roles")
* #JMS\Type("ArrayCollection<Role>")
* #JMS\Groups({"...."})
*
*/
private $roles;
In this case Jms will expect to get and array of arrays just like LBA mentioned. If instead you want he keep the current structure ("roles":["1","2","3"]) instead of "roles":["id": 1], ["id": 2], ["id": 3]], there is an alternative. You can extend the JsonDeserializationVisitor and this a very powerful tool in your arsenal to do almost anything you like with jms.
To do this first change your #Type like this(you will understand why latter)
* #JMS\Type("ArrayCollection<Role,Expand<id>>")
Now you use parameter overwrite, to extend JsonDeserializationVisitor, like this
<parameter key="jms_serializer.json_deserialization_visitor.class">MyBundle\Services\JsonDeserializationVisitor.php</parameter>
And then go and define the new Visitor something like this.
<?php
namespace MyBundle\Services\JmsSerializer;
use JMS\Serializer\Context;
use JMS\Serializer\JsonDeserializationVisitor as ParentJsonDeserializationVisitor;
use JMS\Serializer\Metadata\ClassMetadata;
use JMS\Serializer\Metadata\PropertyMetadata;
class JsonDeserializationVisitor extends ParentJsonDeserializationVisitor
{
/**
* #param PropertyMetadata $metadata
* #param mixed $data
* #param Context $context
*/
public function visitProperty(PropertyMetadata $metadata, $data, Context $context)
{
//This type is the information you put into the #Type annotation.
$type = $metadata->type;
$expand = null;
.......
/*Here you can extract the Expand<id> part that you added to the #Type config.
The Expand part will help you identify the fact that this property needs to be expanded and the id part will tell you how to expand id.
Based on if you do find this you will probably set a variable like $expand = $key, where $key is the "id" part.*/
......
if ($expand !== null) {
$expandedData = [];
foreach($data as $key->$value)
{
$expandedData[$key]=["$expand":$value];
}
parent::visitProperty($metadata, $expandedData, $context);
} else {
parent::visitProperty($metadata, $data, $context);
}
}
This is the basic stuff. Feel free to refactor the code however you like, this is just for fast proof of concept. Also Expand is just how i named this into the exemple. You can use it with whatever name you like. Sorry for not providing the code to extract this from $type but i don't remember the structure of $type right now. Also the structure will change if you do something like Expand<'id'> so play with it and see which fits best for you. Basically with this method you can extend and add features to any jms type you want. For instance you can add something like
#JMS\Type("string<translatable>")
And then extend JsonSerializationVisitor:visitString to call $translator->trans($data) on $data before returning it, and so you can translate a string before serializing it.
Something like this
<?php
namespace MyBundle\Service\JmsSerializer;
use JMS\Serializer\Context;
use JMS\Serializer\JsonSerializationVisitor as ParentJsonSerializationVisitor;
use Symfony\Component\Translation\Translator;
class JsonSerializationVisitor extends ParentJsonSerializationVisitor
{
/**
* #var Translator;
*/
private $translator;
const TRANSLATABLE = "translatable";
/**
* #param string $data
* #param array $type
* #param Context $context
* #return string
*/
public function visitString($data, array $type, Context $context)
{
$translatable = $this->getParameters(self::TRANSLATABLE, $type['params']);
if ($translatable) {
$data = (string)$this->translator->trans($data);
}
return parent::visitString($data, $type, $context);
}
.....................
Hope this helps. Let me know if you have any questions.
Alexandru Cosoi
It is deserializing your array, but it tries to deserialize it into an array of objects of type AppBundle\Entity\Role which seems not to be compatible with your values "1", "2" and so on and therefore throws an error as it cannot instansiate the objects.
You'll have to make sure that your content fits to the expected class.
If you can share your Class Definition for Role we might be able to help you how your array should look like (e.g. something like [["id": 1], ["id": 2], ["id": 3]] probably).

symfony2 best way to test/get a session attribute

I do this to test and get session attribute in my code :
if ($session->has("myVar")) {
$myVar = session->get("myVar");
/* do something */
}
But, I read the code of session and :
/**
* Returns an attribute.
*
* #param string $name The attribute name
* #param mixed $default The default value if not found.
*
* #return mixed
*
* #api
*/
public function get($name, $default = null);
So, if the session attribute is not find, get return "null".
if ($myVar = $session->get("myVar")) {
/* do something */
}
Or better with false, if you have "myVar" but empty, you can't rely on "null" :
if ($myVar = $session->get("myVar", false)) {
/* do something */
}
according to : Null vs. False vs. 0 in PHP
I think the third is the best, one call to $session->get, instead of has and get in my actual code.
I read about alternative comparaison with ternary operator, http://fabien.potencier.org/article/48/the-php-ternary-operator-fast-or-not, I don't use it, mostly because I.m not familiar with, but, if it's not faster, I don't need it.
Can you confirm, third is the best, and if it's not, why, and how to do best ?
That depends on what you want to achieve.
First Option
if ($session->has("myVar")) {
$myVar = session->get("myVar");
/* do something */
}
Makes sense if you want to make sure, that this var is set, and if not you actually want to set it or do anything else. It presumes that having this session variable present is a necessity
Second Option
$myVar = $session->get("myVar");
This one makes sense, if you are comfortable receiving the expected result or a null value as default if not set.
Recommendation:
$myVar = $session->get("myVar");
if (null === $myVar) {
/* do something */
}
Third Option
$myVar = $session->get("myVar", false);
This one simply allows you to override the default value if this session variable is not set
Recommendation:
$myVar = $session->get("myVar", false);
if (!$myVar) {
/* do something */
}
So, in my opinion it depends what you want to do. But there is no best or worst way as you asked for, since they all differ from each other.

Is there a PHP equivalent to the C# summary tag?

Is there anyway to give text editors summary information in a tooltip for custom functions/classes etc. in the way that they can do for standard libraries while coding?
Failing this what is the standard way to highlight the purpose, required params etc. for a function/class in PHP.
Check out PHPDocumentor.
An example would be:
/**
* Set the data
*
* #access public
* #param string $field
* #param mixed $value
*/
public function __set($field, $value)
{
$this->_data[$field] = $value;
}
/**
* Get the data
*
* #access public
* #param string $field
* #return mixed
*/
public function __get($field)
{
return isset($this->_data[$field]) ? $this->_data[$field] : NULL;
}
As the comments self-explain, you use #access to show the visibility of the method (if the code being summarized is a method, of course), #paramto show each parameter, and #return to show the type of the data being returned. There are many different tags to document many different aspects of the code.
You can use the PHPDoc standard for letting your IDE give you hints about, for example, a function.
Just before a function declaration you could have:
/**
* This is a DocBlock comment
*/
function foo(){
//....
}
I've used it in Netbeans and can say that it works quite nicely.

Auto-completion for Zend Form Elements

When creating form elements with Zend (using Zend Studio for Eclipse), I'd like some auto completion or hints. Here's what I'm thinking. I'm sure these exist, but I don't know how to get them.
I type createElement and auto-completes gives me the signature createElement($type, $name). Great, I select it.
but when I try to set the $type I don't get any hints like DateTextBox or ValidationTextBox. Being new, I see how this can be useful. What do you do to remember all the options?
for the array of attributes like require, invalidMessage, I'd like to get a list of those to choose from, and/or auto-complete when I start typing one.
// Date field
$date = $this->createElement('DateTextBox', 'date',
array('require' => 'true', 'invalidMessage' => 'Invalid date format')
);
$date->setLabel('date')->setRequired(true);
You have few options to help yourself, without waiting for any plugin:
learn it and remember ;)
extend your phpDoc blocks with all available options:
Example (to be honest I don't know if Eclipse supports html in phpDoc or even any text after variable name in #param, but it works fine in Netbeans):
/**
* [...]
* #param string $type Can be: <ul><li>DateTextBox</li><li>ValidationTextBox</li></ul>
* #param string $name Whatever
* #param array|Zend_Config $options Array with following keys: <ul><li>require</li><li>invalidMessage</li></ul>
* #return Zend_Form_Element
*/
public function createElement($type, $name, $options = null)
extend Zend class and create your own methods to simplify your work
Example:
class My_Zend_Form_Element extends Zend_Form_Element
{
public function createDateTextBox($name, $options = null)
{
return $this->createElement('DateTextBox', $name, $options);
}
}
declare some well named constants and provide some hint in phpDoc
Example: (type ZFE_OPTIONS and IDE should show hint with some constants to use as array keys)
/**
* Can be true or false
*/
define('ZFE_OPTIONS_REQUIRE','require');
create your own helper classes with methods to produce valid options array
Example:
class ZFE_Options
{
protected $opts = array();
/**
* #param bool $req
* #return ZFE_Options
*/
public function setRequired($req){
$this->opts['require'] = (bool)$req;
return $this;
}
/**
* #param string $txt
* #return ZFE_Options
*/
public function setInvalidMessage($txt){
$this->opts['invalidMessage'] = (string)$txt;
return $this;
}
/**
* #return array
*/
public function toArray(){
return $this->opts;
}
}
$zfe_options = new ZFE_Options();
$opts = $zfe_options
->setRequired(true)
->setInvalidMessage('Please provide valid email address')
->toArray();
That's not possible. It's not how autocompletion works. The hints you get are taken directly from ZF's code documentation. Nothing more, nothing less. Everything you see as hints is taken directly from the DocBlock and method signature, e.g.
/**
* Create an element
*
* Acts as a factory for creating elements. Elements created with this
* method will not be attached to the form, but will contain element
* settings as specified in the form object (including plugin loader
* prefix paths, default decorators, etc.).
*
* #param string $type
* #param string $name
* #param array|Zend_Config $options
* #return Zend_Form_Element
*/
public function createElement($type, $name, $options = null)
Eclipse can tell you to insert a string or an array and it will know that the method returns a Zend_Form_Element, but it cannot tell you what these strings should be.
The only place where I know something like what you describe exists is for CSS files. For some reason, when I type in display: it will give me an autocomplete box with possible values for this declaration. If you want more sophisticated autocomplete like this, consider filing this as a feature request to Zend.

fetch php method comments

I want to fetch a method's comments,take below method for example:
/**
* Returns the regex to extract all inputs from a file.
* #param string The class name to search for.
* #return string The regex.
*/
public function method($param)
{
//...
}
the result should be
Returns the regex to extract all inputs from a file.
#param string The class name to search for.
#return string The regex.
the way I find is use a function like file_get_content to get file content -> filter the method I want -> fetch the comment use regexp
it seems a bit complicated , is there any convenient way to archive this?
actually you can get a method's doc comments with getDocComment
$ref=new ReflectionMethod('className', 'methodName');
echo $ref->getDocComment();
If you want to use the comment in PHP for something check out getDocComment in php's reflection api
PHP Doc. Like Java Doc.
For a method dump I use this little function I composed.
It fetches all methods from provided class that are public(and thus of use to you).
I personally use a dump() method to nicely format the outputted array of method names and descriptions, but that's not needed if you wish to use it for something else :-)
function getDocumentation($inspectclass) {
/** Get a list of all methods */
$methods = get_class_methods($inspectclass);
/** Get the class name */
$class =get_class($inspectclass);
$arr = [];
foreach($methods as $method) {
$ref=new ReflectionMethod( $class, $method);
/** No use getting private methods */
if($ref->isPublic()) {
$arr[$method] = $ref->getDocComment();
}
}
/** dump is a formatting function I use, feel free to use your own */
return dump($arr);
}
echo getDocumentation($this);

Categories