Since few hours i try to convert doctrine2 entities to csv.
My idea was to convert doctrine entities to array with (in my repository ):
return $query->getArrayResult();
And after, convert this array to csv.
But the convertion array to csv don't work because there are DateTime Object in my field....
Does anybody have a simple way to convert doctrine entities to CSV ?
(ps : I tried to search by myself on many post without success, so sorry to disturb you :-( )
To prevent getting errors while converting to Datetime you will have to do it manually. Iterate across all objects and format the datetime using the following for the DateTime objects:
$date->format('Y-m-d H:i:s');
For example you could do the following:
$csv = "";
foreach ($result as $item)
{
foreach($item as $element)
{
if($element instanceof DateTime)
$csv .= $element->format('Y-m-d H:i:s'); //Converts the Datetime to string for the given format
else
$csv .= $element;
$csv .= ",";
}
$csv .= "\r\n"; //Adds new line
}
echo $csv;
Related
Hove to create custom Repository function who query by json field. I have params column in my database who look like this:
"params": {
"product": "stopper",
"itemIdentifier": ""
}
I want to query record by product value. In this case stopper term.
You can achieve this with a classic example :
In your repository :
For one result
public function findOneProduct($value): ?Params
{
return $this->createQueryBuilder('p')
->andWhere('p.product = :val')
->setParameter('val', $value)
->getQuery()
->getOneOrNullResult()
;
}
For multiple result
public function findParamsByProduct($value): ?Params
{
return $this->createQueryBuilder('p')
->andWhere('p.product = :val')
->setParameter('val', $value)
->orderBy(/*some field */)
->setMaxResults(/*if needed*/)
->getQuery()
->getResults()
;
}
In your controller:
$stoppers = $entityManager->getRepository(Params::class)->findParamsByProduct('stopper');
If I understood your question correctly, you have a table with a column named params. And inside this mysql column, you store JSON text.
And then you want to query that table and filter by looking into the JSON in your column.
This can be a bit tedious and was also highly discouraged in the past (prior to the JSON Type in Mysql 5.7.8).
Best practices would be to have a NoSQL DB such as MongoDB which is actual JSON stored in a collection(table).
Anyways, there is a solution for you.
Taking into account #AppyGG explained how to make a custom repository function.
First of all, we have to make a query using pure SQL.
It can be done two ways:
1.Return arrays containing your data.
$conn = $this->getEntityManager()->getConnection();
$sql = '
SELECT * FROM product p
WHERE p.price > :price
ORDER BY p.price ASC
';
$stmt = $conn->prepare($sql);
$stmt->execute(['price' => $price]);
// returns an array of arrays (i.e. a raw data set)
return $stmt->fetchAll();
2.Return hydrated Entities
use Doctrine\ORM\Query\ResultSetMappingBuilder;
$rsm = new ResultSetMappingBuilder($entityManager);
$rsm->addRootEntityFromClassMetadata('MyProject\Product', 'p');
$sql = '
SELECT * FROM product p
WHERE p.price > :price
ORDER BY p.price ASC
';
$nql = $this->_em->createNativeQuery( $sql, $rsm );
$nql->setParameter('price', $price);
//Return loaded entities
return $nql->getResult();
Now, knowing how to make make a MySQL query with doctrine, we want to select results filtered in JSON data.
I'm am referencing this beautiful stackoverflow which explains it all:
How to search JSON data in MySQL?
The easiest solution proposed in there requires at least MySQL 5.7.8
Your MySQL query would be as follow:
//With $entity->getParams() == '{"params": {"product":"stopper", "itemIdentifier":""}}'
$conn = $this->getEntityManager()->getConnection();
$sql = '
SELECT * FROM Entity e
WHERE JSON_EXTRACT(e.params, "$.params.product") = :product
';
//Or Like this if the column is of Type JSON in MySQL(Not doctrine, yes check MySQL).
$sql = '
SELECT * FROM Entity e
WHERE e.params->"$.params.product" = :product
';
$stmt = $conn->prepare($sql);
$statement->bindValue("product","stopper");
$stmt->execute();
return $statement->fetchAll();
Hope this helps!
P.S: Note that my example uses a column named 'params' with a Json containing also a named attribute 'params', this can be confusing. The intended purpose is to show how to do multiple level filtering.
Update Julu 2018:
I find out problem is something else. The print error method will always print out a encoded html message like the one below. If the message is not showing any extra piece of information means the SQL query is fine.
Original Question:
I tried to update the invite_code by using the $wpdb->update method, but it return strange error, it seems like WordPress convert the single quote to html entity - '
Please help me if anyone knows why it will convert the single quote to HTML entity automatically.
I am not able to do use any WordPress built-in method to update the query because the problem seems to happen at the prepared statement which will use in every built-in method.
WordPress database error: UPDATE exhibitor_invite SET invite_code =
' ;8j8mxfkkubd0kppi082p' ; WHERE id = 10
function createCode() {
$length = 20;
$inviteCode = "";
$characters = "0123456789abcdefghijklmnopqrstuvwxyz";
for ($p = 0; $p < $length; $p++) {
$inviteCode .= $characters[mt_rand(0, strlen($characters))];
}
return $inviteCode;
}
function updateCode($id) {
global $wpdb;
$wpdb->show_errors();
$prefix = $wpdb->prefix;
$invite_code = createCode() ;
// I tried to esc the string, but it doesn't work
// $invite_code = $wpdb->esc_like($invite_code);
// I also tried to use normal query, but it return the same error
// $affected_rows = $wpdb->query( $wpdb->prepare(
// " UPDATE {$wpdb->prefix}exhibitor_invite SET invite_code = %s WHERE id = %d", $invite_code, $id ));
$affected_rows = $wpdb->update( $prefix.'exhibitor_invite',
array('invite_code' => $invite_code),
array('id' => $id),
'%s',
'%d' );
$wpdb->print_error();
if(!is_bool($affected_rows)) {
return $affected_rows > 0;
}
return $affected_rows;
}
Perhaps way too late, but in case not I had the exact same problem and spent hours looking for a solution.
It seems that the WordPress property 'update' of wpdb object is where the problem occurs.
One solution that I found to work is to store the entire SQL string in a variable and then before using it, pass the variable through a PHP function of mysqli_real_escape_string().
PHP manual states:
This function is used to create a legal SQL string that you can use in an SQL statement. The given string is encoded to an escaped SQL string, taking into account the current character set of the connection.
Your solution may look something like this (untested).
$sql_string =
"
UPDATE ${prefix}exhibitor_invite
SET invite_code = %s
WHERE id = %d
";
//procedural style
mysqli_real_escape_string( $your_conn_to_server, $sql_string );
//update
$wpdb->update( $wpdb->prepare(
$sql_string,
array(
$invite_code,
$id
)
), OBJECT );
I have a private method in a controller and when I run the method and try echo out the results in my browser, it just dies. I get a white screen with no profiler on the bottom and nothing shows up in my error_log.
Here is my complete method. Note the "hello" does not echo out so it appears to die at the query. Also note that the 'created' field in the table is a datetime type.
private function garbageCollect()
{
$em = $this->getDoctrine()->getManager();
$dql = 'SELECT r FROM AppBundle:MyEntity r WHERE r.created < :created';
$created = new \DateTime('-50 days');
$result = $em->createQuery($dql)
->setParameters( array( 'created' => $created->format('Y-m-d') ) )
->getResult();
echo "hello"; die; // it never echoes this out so it fails above
... // more code here excluded
return true;
}
What am I doing wrong?
You don't need to format the date object as a string. If the field named created is defined as a Doctrine DateTime, you could simply do:
$created = new \DateTime('-50 days');
$result = $em->createQuery($dql)
->setParameters( array( 'created' => $created ) )
->getResult();
Hope this help
Sorry to everyone who took time to look or comment on this and I appreciate the time you took. It appears that Symfony was consuming all my memory allocated to PHP so I had to bump it up considerably. Now it seems to be working fine. The table was rather large it seems. Thanks!
I am trying to get a row out of a table (gc_test) I created in my Wordpress database. I have read the Wordpress documentation and followed it exactly and still no joy.
The $results array never seems to get populated.
$results = $wpdb->get_row("SELECT * FROM $wpdb->gc_test WHERE coupon_code = $code, ARRAY_A");
if($results['redeemable']=="true"){
$message = "Code is good!";
}
else{
$message = "Code has already been redeemed!";
}
The way you are referring to your custom table is not correct. The correct way is to global $wpdb and the prefix property. The way that you have $code embedded is also not correct for a few reasons - it is likely a string and should be surrounded by single quotes, but no matter what is likely a potential SQL injection vulnerability. Make sure to use $wpdb->prepare() to pass arguments with placeholders of %s for strings and %d for digits. You also have the double quotes in the wrong place - it is including ARRAY_A in with your SQL rather than as an argument to get_rows().
// declare $wpdb.
global $wpdb;
// sql string using $wpdb->prefix and %s placeholder
$sql = "SELECT * FROM {$wpdb->prefix}gc_test WHERE coupon_code = %s";
// pass the sql into prepare()
$query = $wpdb->prepare( $sql, $coupon_code );
// call get_row() and tell it that you want an associative array back
$row = $wpdb->get_row( $query, ARRAY_A );
if ( empty( $row ) ){
// nothing came back from the db
$message = "Code not found.";
} elseif ( isset( $row['redeemable'] ) && $row['redeemable'] == "true" ){
// we got a row and it was redeemable
$message = "Code is good!";
} else {
// something else
$message = "Code has already been redeemed!";
}
Thanks to doublesharp's post I went back and studies the $wpdb->prefix function. Apparently this is pretty important. So I changed my prefix on the table from gc_ to wp_ and then assigned the table to a variable with: {$wpdb->prefix}test and it now works like a charm. Thanks a ton!
I am using the gravity form on my site. I am working on create the custom report for this I have need gravity form fields name and id based on specific form id.Please let me know how I can do it.
I am using the following function but it is showing all forms info based on it. it is looking very hard to parse it. Please let me know any function so I can get fields name easily.
$forms = RGFormsModel::get_forms_by_id(13);
try this
function get_all_form_fields($form_id){
$form = RGFormsModel::get_form_meta($form_id);
$fields = array();
if(is_array($form["fields"])){
foreach($form["fields"] as $field){
if(isset($field["inputs"]) && is_array($field["inputs"])){
foreach($field["inputs"] as $input)
$fields[] = array($input["id"], GFCommon::get_label($field, $input["id"]));
}
else if(!rgar($field, 'displayOnly')){
$fields[] = array($field["id"], GFCommon::get_label($field));
}
}
}
//echo "<pre>";
//print_r($fields);
//echo "</pre>";
return $fields;
}
It's not that hard to parse:
$fields=array();
foreach ( $forms['fields'] as $field ) {
$fields[]=array($field['id'] => $field['inputName']);
}
P.S. I'm assuming you use Gravity Forms < 1.7 as RGFormsModel::get_forms_by_id is a deprecated function since 1.7
// Get the Form fields
$form = RGFormsModel::get_form_meta($form_id);
// Run through the fields to grab an object of the desired field
$field = RGFormsModel::get_field( $form, $field_id );
I use the above to get a specific field I want to filter the value of. The $field contains an object with all the properties you want.
echo $field->label // Gets the label
echo $field->inputName // Gets the name
echo $field->type // Gets the type
echo $field->cssClass // Gets the CSS Classes as a string
You are able to get the entered value/content of a field by using rgpost() and by referencing the id ($field->id).
// Check the entered value of every field
foreach( $form['fields'] as &$field ) {
// Get the content for the specific field
$fieldContent = rgpost( "input_".$field->id );
// Check the content
if ( $fieldContent == ... ){}
}