Map PHP boolean to String t/f in Oracle - oracle

I'm refactoring an old application with an Oracle database using Symfony2 and Doctrine. I can't change the database scheme.
I need a boolean value in the model, but the database saves it as VARCHAR2(1 CHAR) with t or f. How can I access and write t/f on Oracle side and use it as boolean in Symfony?
Thanks!
Mitja

Like this in your entity:
/**
* #var string
*
* #ORM\Column(name="somefield", type="string", length=1)
*/
private $someField;
/**
* Set someField
*
* #param boolean $someField
* #return ...
*/
public function setSomeField(bool $someField)
{
$this->someField = 'f';
if($someField)
$this->someField = 't';
return $this;
}
/**
* Get someField
*
* #return boolean
*/
public function getSomeField()
{
if($this->someField == 't')
return true;
return false;
}

Related

Symfony entity - Oracle default SYSDATE not working

Symfony 5 + Oracle.
Entity:
/**
* #var \DateTime
*
* #ORM\Column(name="CREATE_DT", type="date", nullable=false, options={"default"="SYSDATE"})
*/
private $createDt = 'SYSDATE';
Controller:
//save entity object to database (createDt property NOT passed, default must be applied)
$em->persist($obj);
$em->flush();
Error:
Could not convert PHP value 'SYSDATE' of type 'string' to type 'date'. Expected one of the following types: null, DateTime (500 Internal Server Error)
How can I make Symfony apply default SYSDATE at flush?
You can init your date with default value directly in the constructor.
class YourEntity {
/**
* #var \DateTime
*
* #ORM\Column(name="CREATE_DT", type="date", nullable=false)
*/
private $createDt;
public function __construct() {
$this->createDt = new \Datetime();
}
}

Store JSON data into TEXT mysql column with doctrine

I have an entity with one TEXT (MySQL) attributes
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\Table;
use Doctrine\ORM\Mapping\Index;
use ApiPlatform\Core\Annotation\ApiProperty;
/**
* #ApiResource(
* attributes={},
* collectionOperations={
* "get"={},
* "post"={
* "access_control"="is_granted('ROLE_COMPANY')"
* },
* },
* itemOperations={
* "get"={},
* "put"={"access_control"="is_granted('ROLE_COMPANY')"},
* }
* )
* #ORM\Entity(
* repositoryClass="App\Repository\SettingRepository",
* )
* #ORM\Table(
* indexes={#Index(name="domain_idx", columns={"domain"})}
* )
*/
class Setting
{
/**
* #var Uuid
* #ApiProperty(identifier=true)
* #ORM\Id
* #ORM\Column(type="string")
* #ORM\GeneratedValue(strategy="NONE")
*/
private $identifier;
/**
* #ORM\Column(type="text", nullable=true)
*/
private $data = array();
/**
* #ORM\Column(type="string", nullable=true)
*/
private $domain = array();
public function getData()
{
if($this->data == null) return array();
$data = unserialize($this->data);
return $data;
}
public function setData($data): self
{
$this->data = serialize($data);
return $this;
}
/**
* #return mixed
*/
public function getIdentifier()
{
return $this->identifier;
}
/**
* #param mixed $key
*/
public function setIdentifier($identifier): self
{
$this->identifier = $identifier;
return $this;
}
/**
* #return mixed
*/
public function getDomain()
{
return $this->domain;
}
/**
* #param mixed $domain
*/
public function setDomain($domain): self
{
$this->domain = $domain;
return $this;
}
}
If I try to invoke the service with the following parameter structure it works fine:
{
"data": "testData",
"identifier": "testIdentifier",
"domain": "domain1"
}
But If I would like to store an embedded JSON string, for example:
"data": {"temp": 123}
I receive the following error:
hydra:description": "The type of the \"data\" attribute must be \"string\", \"array\" given.",
I tried to convert the object into an string in the method setData. But this method will not be invoked. It seams, that the API-Platform detects the wrong type and throws the exception.
I found some comments, that it is necessary to decorate the property:
https://api-platform.com/docs/core/serialization/#decorating-a-serializer-and-adding-extra-data
Can anyone give me an example? It does not work!
Where is the right place to serialise and unserialise the property data?
Does anyone have an idea?
Kind regards
You need to set the column type to json in MySQL. It should behave as expected.
/**
* #var array Additional data describing the setting.
* #ORM\Column(type="json", nullable=true)
*/
private $data = null;
I think null is more consistent than an empty array, but that's your choice.

What is the best way for reusable values throughout the application in Symfony 3?

I want to have a file or list that I can update easily with values that might change throughout my application.
I don't really want to hard code text values into the templates. I prefer to have all of these values in one place and labelled correctly.
Examples of values that might get updated are:
Page title
Logo text
Brand or company name
I have thought about two options:
Add them to the twig config in config.yml. This is a bit messy and doesn't seem organised if I decide to put a lot of values there.
Make a database table for these and include the entity in each controller where I need to use the values. This might be creating too much work.
Are there any other options or are one of these more suitable?
Thank you.
You need to create a twig function and use it to return the value you want. For example:
namespace AppBundle\Twig;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
class TwigExtension extends \Twig_Extension implements ContainerAwareInterface
{
use ContainerAwareTrait;
/**
* #var ContainerInterface
*/
protected $container;
public function getFunctions()
{
return array(
new \Twig_SimpleFunction('parameter', function($name)
{
try {
return $this->container->getParameter($name);
} catch(\Exception $exception) {
return "";
}
})
);
}
/**
* Returns the name of the extension.
*
* #return string The extension name
*/
public function getName()
{
return 'app.twig.extension';
}
}
This will create a function called parameter and once you call it in twig {{ parameter('my.parameter') }} it will return the parameter. You need to load it as a service, which you can do by adding the following to your services.yml file:
app.twig.extension:
class: AppBundle\Twig\TwigExtension
calls:
- [setContainer, ["#service_container"]]
tags:
- { name: twig.extension }
From personal experience people usually want to be able to change some of the parameters. This is why I usually prefer to create a Setting or Parameter entity which would look something like this:
/**
* Setting
*
* #ORM\Table(name="my_parameters")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ParameterRepository")
*/
class Parameter
{
/**
* #var integer
*
* #ORM\Id
* #ORM\Column(name="parameter_id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="value", type="text", nullable=true)
*/
private $value;
/**
* #param string|null $name
* #param string|null $value
*/
public function __construct($name = null, $value = null)
{
$this->setName($name);
$this->setValue($value);
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Parameter
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set value
*
* #param string $value
*
* #return Parameter
*/
public function setValue($value = null)
{
$this->value = serialize($value);
return $this;
}
/**
* Get value
*
* #return string
*/
public function getValue()
{
$data = #unserialize($this->value);
return $this->value === 'b:0;' || $data !== false ? $this->value = $data : null;
}
}
Then I would add a CompilerPass which will help get all of the parameters from the database and cache them so that your app doesn't make unnecessary sql queries to the database. That might look something similar to the following class:
// AppBundle/DependencyInjection/Compiler/ParamsCompilerPass.php
namespace AppBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class ParamsCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$em = $container->get('doctrine.orm.default_entity_manager');
$settings = $em->getRepository('AppBundle:Parameter')->findAll();
foreach($settings as $setting) {
// I like to prefix the parameters with "app."
// to avoid any collision with existing parameters.
$container->setParameter('app.'.strtolower($setting->getName()), $setting->getValue());
}
}
}
And finally, in your bundle class (i.e. src/AppBundle/AppBundle.php) you add the compiler pass:
namespace AppBundle;
use AppBundle\DependencyInjection\Compiler\ParamsCompilerPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AppBundle extends Bundle
{
public function build(ContainerBuilder $builder)
{
parent::build($builder);
$builder->addCompilerPass(new ParamsCompilerPass(), , PassConfig::TYPE_AFTER_REMOVING);
}
}
Now you can create a DoctrineFixture template to load the parameters you use all the time. With the TwigExtension you will still be able to call the parameter from the twig template and you can create a web UI to change some of the parameters/settings.

Yii- Caching with CSqlDataprovider

Is it possible to do caching of data from sql server queries when using CSqlDataProvider. If so can anyone please provide some links for documentation about it. Or if you have done it personally please guide.
I did a search but found nothing :(
There is some example of implementing this feature
<?php
class CachedSqlDataProvider extends CDataProvider
{
public $queryCache;
public $queryCacheLife;
/**
* #var CDbConnection the database connection to be used in the queries.
* Defaults to null, meaning using Yii::app()->db.
*/
public $db;
/**
* #var string the SQL statement to be used for fetching data rows.
*/
public $sql;
/**
* #var array parameters (name=>value) to be bound to the SQL statement.
*/
public $params=array();
/**
* #var string the name of key field. Defaults to 'id'.
*/
public $keyField='id';
/**
* Constructor.
* #param string $sql the SQL statement to be used for fetching data rows.
* #param array $config configuration (name=>value) to be applied as the initial property values of this class.
*/
public function __construct($sql,$config=array())
{
$this->sql=$sql;
foreach($config as $key=>$value)
$this->$key=$value;
}
/**
* Fetches the data from the persistent data storage.
* #return array list of data items
*/
protected function fetchData()
{
$sql=$this->sql;
$db=$this->db===null ? Yii::app()->db : $this->db;
$db->active=true;
if(($sort=$this->getSort())!==false)
{
$order=$sort->getOrderBy();
if(!empty($order))
{
if(preg_match('/\s+order\s+by\s+[\w\s,]+$/i',$sql))
$sql.=', '.$order;
else
$sql.=' ORDER BY '.$order;
}
}
if(($pagination=$this->getPagination())!==false)
{
$pagination->setItemCount($this->getTotalItemCount());
$limit=$pagination->getLimit();
$offset=$pagination->getOffset();
$sql=$db->getCommandBuilder()->applyLimit($sql,$limit,$offset);
}
if( $this->queryCache == true && $this->queryCacheLife > 0 )
$command=$db->cache( $this->queryCacheLife )->createCommand($sql);
else
$command=$db->createCommand($sql);
foreach($this->params as $name=>$value)
$command->bindValue($name,$value);
return $command->queryAll();
}
/**
* Fetches the data item keys from the persistent data storage.
* #return array list of data item keys.
*/
protected function fetchKeys()
{
$keys=array();
foreach($this->getData() as $i=>$data)
$keys[$i]=$data[$this->keyField];
return $keys;
}
/**
* Calculates the total number of data items.
* This method is invoked when {#link getTotalItemCount()} is invoked
* and {#link totalItemCount} is not set previously.
* The default implementation simply returns 0.
* You may override this method to return accurate total number of data items.
* #return integer the total number of data items.
*/
protected function calculateTotalItemCount()
{
return 0;
}
}
?>

Typo3 Extbase Set and Get values from Session

I am writing an extbase extension on typo3 v6.1
That extension suppose to do a bus ticket booking.
Here what my plan is, user will select date and number of seats and submit the form.
Here my plan to push the date and rate of the selected seat to session (Basket).
And while making payment, I wanted to get that values from session and after payment I need to clear that particular session.
So In short, How to Push and retrieve the values to and from the session in extbase.
Any suggestions ?
Thank you.
There are different ways. The simplest would be for writing in the session
$GLOBALS['TSFE']->fe_user->setKey("ses","key",$value)
and for reading values from the session
$GLOBALS["TSFE"]->fe_user->getKey("ses","key")
I'm using for this a service class.
<?php
class Tx_EXTNAME_Service_SessionHandler implements t3lib_Singleton {
private $prefixKey = 'tx_extname_';
/**
* Returns the object stored in the userĀ“s PHP session
* #return Object the stored object
*/
public function restoreFromSession($key) {
$sessionData = $GLOBALS['TSFE']->fe_user->getKey('ses', $this->prefixKey . $key);
return unserialize($sessionData);
}
/**
* Writes an object into the PHP session
* #param $object any serializable object to store into the session
* #return Tx_EXTNAME_Service_SessionHandler this
*/
public function writeToSession($object, $key) {
$sessionData = serialize($object);
$GLOBALS['TSFE']->fe_user->setKey('ses', $this->prefixKey . $key, $sessionData);
$GLOBALS['TSFE']->fe_user->storeSessionData();
return $this;
}
/**
* Cleans up the session: removes the stored object from the PHP session
* #return Tx_EXTNAME_Service_SessionHandler this
*/
public function cleanUpSession($key) {
$GLOBALS['TSFE']->fe_user->setKey('ses', $this->prefixKey . $key, NULL);
$GLOBALS['TSFE']->fe_user->storeSessionData();
return $this;
}
public function setPrefixKey($prefixKey) {
$this->prefixKey = $prefixKey;
}
}
?>
Inject this class into your controller
/**
*
* #var Tx_EXTNAME_Service_SessionHandler
*/
protected $sessionHandler;
/**
*
* #param Tx_EXTNAME_Service_SessionHandler $sessionHandler
*/
public function injectSessionHandler(Tx_EXTNAME_Service_SessionHandler $sessionHandler) {
$this->sessionHandler = $sessionHandler;
}
Now you can use this session handler like this.
// Write your object into session
$this->sessionHandler->writeToSession('KEY_FOR_THIS_PROCESS');
// Get your object from session
$this->sessionHandler->restoreFromSession('KEY_FOR_THIS_PROCESS');
// And after all maybe you will clean the session (delete)
$this->sessionHandler->cleanUpSession('KEY_FOR_THIS_PROCESS');
Rename Tx_EXTNAME and tx_extname with your extension name and pay attention to put the session handler class into the right directory (Classes -> Service -> SessionHandler.php).
You can store any data, not only objects.
HTH
From Typo3 v7 you can also copy the native session handler (\TYPO3\CMS\Form\Utility\SessionUtility) for forms and change it to your needs. The Class makes a different between normal and logged in users and it support multiple session data seperated by the sessionPrefix.
I did the same and generalized the class for a more common purpose. I only removed one method, change the variables name and added the method hasSessionKey(). Here is my complete example:
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
/**
* Class SessionUtility
*
* this is just a adapted version from \TYPO3\CMS\Form\Utility\SessionUtility,
* but more generalized without special behavior for form
*
*
*/
class SessionUtility {
/**
* Session data
*
* #var array
*/
protected $sessionData = array();
/**
* Prefix for the session
*
* #var string
*/
protected $sessionPrefix = '';
/**
* #var TypoScriptFrontendController
*/
protected $frontendController;
/**
* Constructor
*/
public function __construct()
{
$this->frontendController = $GLOBALS['TSFE'];
}
/**
* Init Session
*
* #param string $sessionPrefix
* #return void
*/
public function initSession($sessionPrefix = '')
{
$this->setSessionPrefix($sessionPrefix);
if ($this->frontendController->loginUser) {
$this->sessionData = $this->frontendController->fe_user->getKey('user', $this->sessionPrefix);
} else {
$this->sessionData = $this->frontendController->fe_user->getKey('ses', $this->sessionPrefix);
}
}
/**
* Stores current session
*
* #return void
*/
public function storeSession()
{
if ($this->frontendController->loginUser) {
$this->frontendController->fe_user->setKey('user', $this->sessionPrefix, $this->getSessionData());
} else {
$this->frontendController->fe_user->setKey('ses', $this->sessionPrefix, $this->getSessionData());
}
$this->frontendController->storeSessionData();
}
/**
* Destroy the session data for the form
*
* #return void
*/
public function destroySession()
{
if ($this->frontendController->loginUser) {
$this->frontendController->fe_user->setKey('user', $this->sessionPrefix, null);
} else {
$this->frontendController->fe_user->setKey('ses', $this->sessionPrefix, null);
}
$this->frontendController->storeSessionData();
}
/**
* Set the session Data by $key
*
* #param string $key
* #param string $value
* #return void
*/
public function setSessionData($key, $value)
{
$this->sessionData[$key] = $value;
$this->storeSession();
}
/**
* Retrieve a member of the $sessionData variable
*
* If no $key is passed, returns the entire $sessionData array
*
* #param string $key Parameter to search for
* #param mixed $default Default value to use if key not found
* #return mixed Returns NULL if key does not exist
*/
public function getSessionData($key = null, $default = null)
{
if ($key === null) {
return $this->sessionData;
}
return isset($this->sessionData[$key]) ? $this->sessionData[$key] : $default;
}
/**
* Set the s prefix
*
* #param string $sessionPrefix
*
*/
public function setSessionPrefix($sessionPrefix)
{
$this->sessionPrefix = $sessionPrefix;
}
/**
* #param string $key
*
* #return bool
*/
public function hasSessionKey($key) {
return isset($this->sessionData[$key]);
}
}
Don't forget to call the initSession first, every time you want use any method of this class

Resources