ZF2 Zend\Db Insert/Update Using Mysql Expression (Zend\Db\Sql\Expression?) - php

Is there any way to include MySQL expressions like NOW() in the current build of ZF2 (2.0.0beta4) through Zend\Db and/or TableGateway insert()/update() statements?
Here is a related post on the mailing list, though it hasn't been answered: http://zend-framework-community.634137.n4.nabble.com/Zend-Db-Expr-and-Transactions-in-ZF2-Db-td4472944.html
It appears that ZF1 used something like:
$data = array(
'update_time' => new \Zend\Db\Expr("NOW()")
);
And after looking through Zend\Db\Sql\Expression I tried:
$data = array(
'update_time' => new \Zend\Db\Sql\Expression("NOW()"),
);
But get the following error:
Catchable fatal error: Object of class Zend\Db\Sql\Expression could not be converted to string in /var/www/vendor/ZF2/library/Zend/Db/Adapter/Driver/Pdo/Statement.php on line 256
As recommended here: http://zend-framework-community.634137.n4.nabble.com/ZF2-beta3-Zend-Db-Sql-Insert-new-Expression-now-td4536197.html I'm currently just setting the date with PHP code, but I'd rather use the MySQL server as the single source of truth for date/times.
$data = array(
'update_time' => date('Y-m-d H:i:s'),
);
Thanks, I appreciate any input!

Zend_Db_Sql_Expression works for me now.
$data = array(
'update_time' => new \Zend\Db\Sql\Expression("NOW()"),
);

I am not sure if they fixed this in the latest updates, but it was a know bug and even if they said it was fixed, for me it still didn't work after the fix.

It works for me too. Maybe, your problem was like mine. The string error conversion was because the parameter that I passed to method was elements of array and not the array. Check this and have sure that you are passing $object->method($array).

You can try:
\Zend\Db\Sql\Predicate\Literal();
//or
\Zend\Db\Sql\Literal();
------------------------------------
$data = array(
'update_time' => new \Zend\Db\Sql\Literal("NOW()"),
);
https://framework.zend.com/manual/2.2/en/modules/zend.db.sql.html#literal-literal

Related

How to parse function name with arguments in PHP?

I am building a module for my own PHP framework, so my question is very specific and special. It's difficult to explain my question so I will go ahead and show it on code below.
I have a little piece of PHP in a $code variable, it looks like this:
$code = "___echo(TODAY_IS, date('j.n.Y', time()), time());";
What I need is to parse this $code variable and I want to get this result:
$result = array(
'function_name' => "___echo",
'arguments' => array(
0 => "TODAY_IS",
1 => "date('j.n.Y', time())",
2 => "time()"
)
);
I am thinking and I have tried using some regex, but neither worked sufficiently well. I also tried using Tokenizer, however I wasn't successful either.
Thanks for any hints or help in advance.
Here is a shot using PHP-Parser. It's likely going to be more useful than tokenizer or some freaky regex.
Example:
$code = "___echo(TODAY_IS, date('j.n.Y', time()), time());";
$parser = new PhpParser\Parser(new PhpParser\Lexer);
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
$statements = $parser->parse("<?php $code");
$result['function_name'] = $statements[0]->name->toString();
foreach ($statements[0]->args as $arg) {
$result['arguments'][] = $prettyPrinter->prettyPrint(array($arg));
}
var_export($result);
Output:
array (
'function_name' => '___echo',
'arguments' =>
array (
0 => 'TODAY_IS',
1 => 'date(\'j.n.Y\', time())',
2 => 'time()',
),
)
token_get_all() function is what you need here:
token_get_all("<?php ___echo(TODAY_IS, date('j.n.Y', time()), time());")
This returns a list of tokens parsed from the given string. See the tokens documentation for recognizing the items of the list.
In my opinion, tokenizer-based solution should be preferred over any regular expressions based on whatever is written in the PHP manual regarding syntax.

Elasticsearch boosting syntax PHP

I did read the elasticsearch documentation but it lacks examples, for me.
I have put some documents in the es-engine, they contain the field "text" and "title".
Now I want to boost up the hits in the field "title". I'm using the php-api.
I tried this one:
$params_ci['index'] = 'all';
$params_ci['type'] = 'all';
$params_ci['body']['query']['query_string']['query'] = $query;
$params_ci['body']['function_score']['functions']['field_value_factor'] = array('field' => 'title',
'factor' => 1.2)
$client = ElasticClientFactory::build();
$client->search($params_ci)
But I get an error. Without the "function_score" it works.
... Parse Failure [No parser for element [function_score] ...
The biggest problem for me is how to translate the JSON in the documentation into the right place as arrays. I know JSON is like an array but often it fits not in my hierarchy of array?
Uses ElasticSearch Version: elasticsearch-1.1.1
The right synax is:
$params_ci['body']['query']['function_score']['functions']['field_value_factor'] = array('field' => 'title', 'factor' => 1.2)

Cake PHP Where Clause

I am trying to learn CakePHP and I have a simple question,
I have
$this->set('settings', $this->Setting->find('all'));
in a Controller. I want to concentrate this down to:
find all settings where the type is equal to General
How could I do this?
You can use findAllBy function.
findAllBy(string $value, array $fields, array $order, int
$limit, int $page, int $recursive)
You can read this in the CakePHP Cookbook
So your example will look like this:
$this->Setting->findAllByType('General');
$this->Setting->findAllByType($variable); //If you want to use a variable
Or
$this->Setting->find('all', array('conditions' => array('type' => $type)));
Or (NOT Recommended)
$this->Setting->query("SELECT * FROM settings WHERE type = 'General';");
Simply you may still able to use find method of your model object by supplying it with parameters.
$settings = $this->Setting->find('all', array('conditions' => array('type' => 'General')));
$this->set('settings', $settings);
The most important thing for you as a beginner, regarding this question, is to check out this link.

Symfony sfWidgetFormDoctrineChoice with multiple option on

I have created a form in which i embed another form. My question is about this embedded form - I'm using a sfWidgetFormDoctrineChoice widget with option multiple set to true. The code for this embedded form's configure method:
public function configure()
{
unset($this['prerequisite_id']);
$this->setWidget('prerequisite_id', new sfWidgetFormDoctrineChoice(array(
'model' => 'Stage',
'query' => Doctrine_Query::create()->select('s.id, s.name')->from('Stage s')->where('s.workflow_id = ?', $this->getOption('workflow_id') ),
'multiple' => true
)));
$this->setValidator('prerequisite_id', new sfValidatorDoctrineChoice(array(
'model' => 'Stage',
'multiple' => true,
'query' => Doctrine_Query::create()->select('s.id, s.name')->from('Stage s')->where('s.workflow_id = ?', $this->getOption('workflow_id') ),
'column' => 'id'
)));
}
I unset the prerequisite_id field because it is included in the base form, but I want it to be a multiple select.
Now, when I added the validator, everything seems to work (it passes the validation), but it seems like it has problems saving the records if there is more than one selection sent.
I get this PHP warning after submitting the form:
Warning: strlen() expects parameter 1 to be string, array given in
D:\Development\www\flow_dms\lib\vendor\symfony\lib\plugins\sfDoctrinePlugin\lib\database\sfDoctrineConnectionProfiler.class.php
on line 198
and more - I know, why - in symfony's debug mode I can see the following in the stack trace:
at Doctrine_Connection->exec('INSERT INTO stage_has_prerequisites
(prerequisite_id, stage_id) VALUES (?, ?)', array(array('12', '79'),
'103'))
So, what Symfony does is send to Doctrine an array of choices - and as I see in the debug sql query, Doctrine cannot render the query correctly.
Any ideas how to fix that? I would need to have two queries generated for two choices:
INSERT INTO stage_has_prerequisites (prerequisite_id, stage_id) VALUES (12, 103);
INSERT INTO stage_has_prerequisites (prerequisite_id, stage_id) VALUES (79, 103);
stage_id is always the same (I mean, it's set outside this form by the form in which it is embedded).
I have spend 4 hours on the problem already, so maybe someone is able to provide some help.
Well, I seem to have found a solution (albeit not the best one, I guess). Hopefully it'll be helpful to somebody.
Finally, after much thinking, I have concluded that if the problem comes from the Doctrine_Record not being able to save the record if it encounters an array instead of a single value, then the easiest solution would be to overwrite the save() method of the Doctrine_Record. And that's what I did:
class StageHasPrerequisites extends BaseStageHasPrerequisites
{
public function save(Doctrine_Connection $conn = null)
{
if( is_array( $this->getPrerequisiteId() ) )
{
foreach( $this->getPrerequisiteId() as $prerequisite_id )
{
$obj = new StageHasPrerequisites();
$obj->setPrerequisiteId( $prerequisite_id );
$obj->setStageId( $this->getStageId() );
$obj->save();
}
}
else
{
parent::save($conn);
}
}
(...)
}
So now if it encounters an array instead of a single value, it just creates a temporary object and saves it for each of this array's values.
Not an elegant solution, definitely, but it works (keep in mind that it is written for the specific structure of the data and it's just the effect of my methodology, namely See What's Wrong In The Debug Mode And Then Try To Correct It Any Way Possible).

Use of "$or" condition is not working

I am developing a search portal, so I need to find the searched text on more than one field.
I am trying to use the advanced query of MongoDB in PHP.
My code is:
$mongo = new MongoDBCONN();
$jobCollection = $mongo->select('jobs', $mongo);
$advanceQuery=array('orgId' => '21')
$query_q=array('$or'=>array(
array("jobTitle"=>new MongoRegex("/$search/i")),
array("jobLocationCity"=>new MongoRegex("/$search/i")),
array('jobLocationCountry'=>new MongoRegex("/$search/i"))
));
$advanceQuery=array_merge($advanceQuery,$query_q);
$jobCollection->find($advanceQuery);
It returns NULL every time, whereas MongoRegex is working fine, because when I use it to search on only one field it works.
$search is post as input text.
I found the answer on my own, actually this was a version problem. I was using 1.4.4, but after update to 1.7.4 it is working. On the mongo website I found that the "or" operator was included only from version 1.7.x onwards.
$regexObj = new MongoRegex("/$search_term/i");
$where = array(
'$or' => array(
array("Name" => $regexObj),
array("image.caption.text" => $regexObj),
array("image.user.username" => $regexObj)
)
);
$cursor = $collection->find($where);
// Parsing the results
while ($cursor->hasNext())
{
$obj = $cursor->getNext();
$profile_image = $obj['image']['user']['profile_picture'];
}
If you need to combine the regex with another operator, you need to use the $regex clause. That one is missing in your code example. Please read again about how to query with regulars expressions.

Categories