AMFPHP working for ArrayCollection in Flex - apache-flex

I have a function in my php class which must receive an array of Objects. In flex, I send the data (as ArrayCollection) calling the service. If I work locally, the PHP receive the data and store all the records in the database, but i I place such service in the server, the function doesnt work.
public function putPrecioBaseProductos($data) {
$priveID = $data[0]->priveID;
$date = $data[0]->date;
$res = mysql_query("DELETE FROM db.prices WHERE priveID=".$priveID." AND date='".$date."'");
if (!$res) return '0';
$cadena = "";
for ($i=0; $i < count($data); $i++) {
if ($cadena != '') $cadena .= ', ';
$cadena .= "(".$priveID.", ".$data[$i]->productID.", '".$data[$i]->precio1."', '".$data[$i]->precio2."', '".$data[$i]->precio3."', '".$data[$i]->precio4."', '".$data[$i]->precio5."', '".$date."')";
}
$res = mysql_query( "INSERT INTO tabo4.precios_base (proveedorID, productoID, precio1, precio2, precio3, precio4, precio5, fecha) VALUES ".$cadena );
if ($res) return '1'; else return '0';
}
I have been googling and found that amfphp do not support ArrayColletion as parameter but as i have just said, locally (using MAMP), data is received as desired but in server not.
Anyone know why?
Thanks.

Try sending data as Array instead of ArrayCollection.
ArrayCollection does not work well with AMFPhp ...
To get the array just use:
myArrayCollection.source;

Related

ORA-6502, from WEB

I have a problem with Oracle DB.
<?php
require_once 'includes/conn.php';
function connect_db()
{
if ($c=oci_pconnect(uname,pwd, host,'AL32UTF8'))
return $c;
else
die( "ERROR");
}
$conn=connect_db();
$query = "BEGIN :ds_id :=DS.REG_DS1(:F_NAME);END;";
$stmt=oci_parse($conn,$query);
$f_name='John Doe';
$ds_id=-1;
oci_bind_by_name($stmt, ":ds_id", $ds_id);
oci_bind_by_name($stmt, ":F_NAME", $f_name);
if(oci_execute($stmt))
{
echo 'good';
}
else
print_r(oci_error($stmt));
?>
Here is function REG_DS1
FUNCTION REG_DS1(F_NAME IN VARCHAR) RETURN NUMBER AS
DS_ID NUMBER(8,0):=9988;
BEGIN
-- INSERT INTO TEST VALUES(F_NAME,SYSDATE);
RETURN DS_ID;
END REG_DS1;
When I try to execute this function from Sql Developer, it runs with no problem.
But if I execute from PHP script above, it gives me error:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small ORA-06512: at line 1 [offset] => 0 [sqltext] => BEGIN :ds_id :=DS.REG_DS1(:F_NAME);END; )
If i change DS_ID variable to another number less than 100, it works great from both. but if i set it to a number more than 99, it gets me error from php script.
What can be a problem?
--jst idea and this is not solutioN
variable decleration or some defination problem
oci_connect($ODBuser,$ODBpass,$ODBhost,$db_charset);
should try like this
not like
oci_pconnect(uname,pwd, host,'AL32UTF8')
sample code :
-- just idea
<?php
$file = "../script/param.CML";
$encryptObj = new cast128;
$encryptObj->setkey("SABBIllustrateKey");
$fp=fopen($file,'r');
$strContent = fread($fp, filesize($file));
fclose($fp);
$strContent=$encryptObj->decrypt($strContent);
$ArConnect=split(" ",$strContent);
$OraService=$ArConnect[8];
$OraUser=$ArConnect[9];
$OraDBpass=$ArConnect[10];
$db_charset = 'AL32UTF8';
$cursor=oci_connect($OraUser,$OraDBpass,$OraService,$db_charset);
if(!$cursor)
{
echo "<br>Error In connection:- reason<BR>";
$e = oci_error(); // For oci_connect errors pass no handle
}
?>
<?php
$file = "../script/param.CML";
$encryptObj = new cast128;
$encryptObj->setkey("SABBIllustrateKey");
$fp=fopen($file,'r');
$strContent = fread($fp, filesize($file));
fclose($fp);
$strContent=$encryptObj->decrypt($strContent);
$con=split(" ",$strContent);
$OraService=$con[8];
$OraUser=$con[9];
$OraDBpass=$con[10];
$db_charset = 'AL32UTF8';
$cursor=oci_connect($OraUser,$OraDBpass,$OraService,$db_charset);
if(!$cursor)
{
echo "<br>Error In connection:- reason<BR>";
$e = oci_error(); // For oci_connect errors pass no handle
}
?>
Thx guys, finally I solved problem myself.
The problem was in variable size of returning value
By changing
oci_bind_by_name($stmt, ":ds_id", $ds_id);
to
oci_bind_by_name($stmt, ":ds_id", $ds_id,10,SQLT_INT );
the problem was solved.

Symfony2 + DBAL. How to use bindValue for multiple insert?

I'm using DBAL and I want to execute multiple insert query. But I have the problem: bindValue() method not working in loop. This is my code:
$insertQuery = "INSERT INTO `phonebook`(`number`, `company`, `user`) VALUES %s
ON DUPLICATE KEY UPDATE company=VALUES(company), user=VALUES(user)";
for ($i = 0; $i < count($data); $i++) {
$inserted[] = "(':number', ':company', ':user')";
}
$insertQuery = sprintf($insertQuery, implode(",", $inserted));
$result = $db->getConnection()->prepare($insertQuery);
for ($i = 0; $i < count($data); $i++) {
$result->bindValue($data[$i]["number"]);
$result->bindValue($data[$i]["company"]);
$result->bindValue($data[$i]["user"]);
}
$result->execute();
As result I received one-line table with fields: :number, :company, :user.
What am I doing wrong?
Thanks a lot for any help!
The problem you're having is that your binding has no way to determine to which placeholder it should be doing the binding with. To visualize it better, think on the final DBAL query you're generating:
INSERT INTO `phonebook`(`number`, `company`, `user`) VALUES
(':number', ':company', ':user'),
(':number', ':company', ':user'),
(':number', ':company', ':user');
When you do the binding, you're replacing all the parameters at the same time, ending up with a single row inserted.
One possible solution would be to give different parameter names to each row and then replace each one accordingly.
It would look like something similar to this:
public function randomParameterName()
{
return uniqid('param_');
}
...
$parameters = [];
for ($i = 0; $i < count($data); $i++) {
$parameterNames = [
'number' => $this->randomParameterName(),
'company' => $this->randomParameterName(),
'user' => $this->randomParameterName(),
];
$parameters[$i] = $parameterNames;
$inserted[] = sprintf("(':%s', ':%s', ':%s')",
$parameterNames['number'],
$parameterNames['company'],
$parameterNames['user']
);
}
$insertQuery = sprintf($insertQuery, implode(",", $inserted));
$result = $db->getConnection()->prepare($insertQuery);
foreach ($parameters as $i => $parameter) {
$result->bindValue($parameter['number'], $data[$i]["number"]);
$result->bindValue($parameter['company'], $data[$i]["company"]);
$result->bindValue($parameter['user'], $data[$i]["user"]);
}
You could probably extend your $data variable and incorporate the new parameter names into it. This would remove the need of yet another array $parameters to hold reference to the newly created parameter names.
Hope this helps
There is another alternative:
$queryStart = "INSERT INTO {$tableName} (" . implode(', ', array_keys($buffer[0])) . ") VALUES ";
$queryRows = $params = $types = [];
foreach ($rowBuffer as $row) {
$rowQuery = '(' . implode(', ', array_fill(0, count($row), '?')) . ')';
$rowParams = array_values($row);
list($rowQuery, $rowParams, $types) = SQLParserUtils::expandListParameters($rowQuery, $rowParams, $types);
$queryRows[] = $rowQuery;
$params = array_merge($params, $rowParams);
}
$query = $queryStart . implode(', ', $queryRows);
$connection->executeQuery($query, $params, $types);

Get content of an ArrayCollection

I would like to upgrade my symfony 2 project from 2.3 to 2.7 LTS version. I have a problem in a repository to get result of a query. In 2.3, this query give me something :
public function findProtectedPublications( $steps, $start, $end)
{
$query= $this->getEntityManager()
->createQueryBuilder()
->select('d.pubRefs')
->from('ImpressionDemandBundle:Event', 'h')
->innerJoin('h.demand','d')
->where('d.protectedPublications = :pub')
->setParameter('pub', 1 )
->andWhere('h.date >= :start')
->setParameter('start', $start )
->andWhere('h.date <= :end')
->setParameter('end', $end )
->andWhere('h.stepId in (:steps)')
->setParameter('steps', $steps )
->orderBy('d.id','ASC')
->getQuery();
$results = $query->getResult();
$publications = array();
if ($results && ! empty ($results)){
foreach($results as $result){
$pubs = $result['pubRefs'];
if ($pubs && ! empty($pubs)){
foreach($pubs as $pub){
$publications[] = $pub;
}
}
}
}
return $publications;
}
But this code doesn't work in earlier version because $pubs variable in an ArrayCollection. So I changed the end of my code with this :
$results = $query->getResult();
$publications = array();
if ($results && ! empty ($results)){
foreach($results as $result){
$pubs = $result['pubRefs'];
var_dump($pubs);
if (! $pubs->isEmpty()){
$arrayPubs = $pubs->toArray();
foreach($arrayPubs as $pub){
$publications[] = $pub;
}
}
}
}
return $publications;
In this part, when I dump the $pubs variable, I have :
object(Doctrine\Common\Collections\ArrayCollection)#131 (2) {
["elements":"Doctrine\Common\Collections\ArrayCollection":private]=>
NULL
["_elements":"Doctrine\Common\Collections\ArrayCollection":private]=>
array(1) {
[0]=>
object(Impression\DemandBundle\Entity\Publication)#125 (5) {
["editor":"Impression\DemandBundle\Entity\Publication":private]=>
string(24) "Journal Le Monde 4-10-13"
["coauthors":"Impression\DemandBundle\Entity\Publication":private]=>
string(12) "Machin Machin"
["title":"Impression\DemandBundle\Entity\Publication":private]=>
string(57) "La tragédie de Lampedusa: s"émouvoir, comprendre, agir."
["nbPages":"Impression\DemandBundle\Entity\Publication":private]=>
float(1)
["nbCopies":"Impression\DemandBundle\Entity\Publication":private]=>
float(40)
}
}
}
So it seems that there are elements in this ArrayCollection, but the test $pubs->isEmpty() gives a true result, so I have nothing in $publications array.
Edit: In fact, the problem seems to be due to my data in the database : for an object previous from my upgrade, I have something like this in the database :
O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:54:"Doctrine\Common\Collections\ArrayCollection_elements";a:1:{i:0;O:42:"Impression\DemandBundle\Entity\Publication":5:{s:50:"Impression\DemandBundle\Entity\Publicationeditor";s:5:"BREAL";s:53:"Impression\DemandBundle\Entity\Publicationcoauthors";s:5:"MONOT";s:49:"Impression\DemandBundle\Entity\Publicationtitle";s:18:"USA Canada mexique";s:51:"Impression\DemandBundle\Entity\PublicationnbPages";d:150;s:52:"Impression\DemandBundle\Entity\PublicationnbCopies";d:150;}}}
and this gives the error.
For a object add after my upgrade, I have something like this in the database :
O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:53:"Doctrine\Common\Collections\ArrayCollectionelements";a:1:{i:0;O:42:"Impression\DemandBundle\Entity\Publication":5:{s:50:"Impression\DemandBundle\Entity\Publicationeditor";s:8:"dfg dfgd";s:53:"Impression\DemandBundle\Entity\Publicationcoauthors";s:7:"dfg dfg";s:49:"Impression\DemandBundle\Entity\Publicationtitle";s:5:"fdg d";s:51:"Impression\DemandBundle\Entity\PublicationnbPages";d:5;s:52:"Impression\DemandBundle\Entity\PublicationnbCopies";d:3;}}}
and the function findProtectedPublications() works without errors.
The difference between the two versions is ArrayCollection_elements for the first and ArrayCollectionelements for the second.
To correct this data, I tried with
UPDATE demand SET pub_refs = REPLACE (pub_refs, "ArrayCollection_elements', 'ArrayCollectionelements')
but this doesn't work because of special chars. Trying with
UPDATE demand SET pub_refs = REPLACE (pub_refs, "ArrayCollection�_elements', 'ArrayCollection�elements')
doesn't work better. How can I correct this data ?
Doctrine can populate results as an Array instead of an ArrayCollection, simply change the getResult() call to:
$results = $query->getResult(\Doctrine\ORM\AbstractQuery::HYDRATE_ARRAY);
This would be the most efficient way to complete your task however you could also use ArrayCollection's built-in toArray() method to convert its own data to array format:
$publications = $results->toArray();
As the problem seems to be due to a change in the storage of ArrayCollection in database between 2.3 and 2.7 version of symfony, I created an line command to update these in database.

How to execute a php loop in an andWhere clause using QueryBuilder?

I would like to execute this type of query using QueryBuilder in my FakeRepository.php (it's for a search form where the user can check some boxes).
if (sizeof($p['types']) > 0) {
$qb->andWhere(
foreach ($p['types'] as $type_id)
{'type.id=' .$type_id.' OR ' }
'1=0');
}
But I have an error with my syntax but I don't know how to fix it :
Parse error: syntax error, unexpected T_FOREACH, expecting ')' in /MyBundle/Entity/FakeRepository.php
Thanks a lot for your help
You need to first construct your OR condition and then pass it to the query builder
$first = true;
$orQuery = '';
foreach ($p['types'] as $type_id)
if ($first) {
$first = false;
} else {
$orQuery .= ' OR ';
}
$orQuery .= 'type.id=' .$type_id;
}
$qb->andWhere($orQuery);
You can also resove this problem:
$arr = array();
foreach ($p['types'] as $type_id){
$arr[] = $qb->expr()->orX("type.id = $type_id");
}
$qb->andWhere(join(' OR ', $arr));
Another solution to keep QueryBuilder functionality
$orX = $qb->expr()->orX();
foreach ($types as $key => $type) {
$orX->add($qb->expr()->eq('types', ':types'.$key));
$qb->setParameter('types'.$key, $type->getId());
}
$qb->andWhere($orX);

Drupal module_invoke() and i18n

I am tasked with i18n-ing our current CMS setup in Drupal.
The problem that I am facing is with use of module_invoke() to place blocks within nodes.
I have managed to string translate blocks, and that is working when a block is placed in a region (block content is successfully translated) using the UI.
However, when a block is injected into a node like such:
$block = module_invoke('block', 'block', 'view', 22); print $block['content'];
It is not getting translated, or even worse, not showing at all.
I have also tried this variation using t(). e.g.:
$block = module_invoke('block', 'block', 'view', 22); print t($block['content']);
to no avail.
Generally speaking I've having a bit of trouble with blocks for i18n. Does anyone have a recommended approach for dealing with blocks in drupal with regards to translating them? I would prefer not to create different blocks for each language.
So .. After digging around in the bowels of Drupal - and much hair pulling .. I've come up with an almost decent solution.
Basically, with this function, I can extract a translated version of a block:
function render_i18n_block($block_id, $region = "hidden"){
if ($list = block_list($region)) {
foreach ($list as $key => $block) {
// $key == <i>module</i>_<i>delta</i>
$key_str = "block_".$block_id;
if ($key_str == $key){
return theme('block', $block);
}
}
}
}
Then, in my node, I simple call:
<?php echo render_i18n_block(<block_id>,<region>); ?>
There can be some issues where your blocks might not be displaying in a region (and therefore you can't pass a region into block_list). For this case, I simply created a region called "hidden" which is not rendered anywhere in my template, but can be used to call block_list.
Finally (and this is the part that I still need to find a good solution for), I discovered that block_list() in: includes/blocks/block.inc has a bit of an issue.
It appears that $theme_key is not reliably set unless block_list() is being called from the theme() function (in includes/themes.inc) .. this causes the SQL to return an empty results set. The SQL looks like this:
$result = db_query(db_rewrite_sql("SELECT DISTINCT b.* FROM {blocks} b LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta WHERE b.theme = '%s' AND b.status = 1 AND (r.rid IN (". db_placeholders($rids) .") OR r.rid IS NULL) ORDER BY b.region, b.weight, b.module", 'b', 'bid'), array_merge(array($theme_key), $rids));
As you can see, if theme_key is not set, then it will just return an empty result.
For now I am bypassing this by simply adding:
if (!isset($theme_key)){$theme_key="<my_theme_name>";}
in modules/blocks/block.inc::block_list() around line 429 .. I still need to work out a better way to do this.
10 for anyone with suggestions on how I could ensure that $theme_key is set before calling block_list :)
I had exactly the same problem as you, since I was using
$block = module_invoke('block', 'block_view', 'block_id');
print render($block['content']);
to inject the block into my nodes. However, looking up module_invoke in the Drupal reference, I found a comment titled "to render blocks in Drupal 7 better to use Block API", with this code:
function block_render($module, $block_id) {
$block = block_load($module, $block_id);
$block_content = _block_render_blocks(array($block));
$build = _block_get_renderable_array($block_content);
$block_rendered = drupal_render($build);
return $block_rendered;
}
I just un-functioned it to use directly, like so:
$block = block_load('block', 'block_id');
$block_content = _block_render_blocks(array($block));
$build = _block_get_renderable_array($block_content);
print render($build);
And for me it works like a charm. Be aware however that this method prints the block title as well, so maybe you'll want to set it to 'none' in the original language.
Create a function like this
<?php
function stg_allcontent2($allC, $level
= "1") {
global $language; $lang = $language->language;
foreach ($allC as $acKey => $ac) {
if($ac['link']['options']['langcode']
== $lang){ if ($level == "1")
$toR .= "";
if (is_array($ac['below']))
$class="expanded"; else
$class="leaf";
$toR .= "<li class=\"".$class."\">" . l($ac['link']['link_title'], $ac['link']['link_path']) . "</li>";
if ($level != "1") $toR .= ""; if (is_array($ac['below'])) $toR .= "<ul class=\"menu\">".stg_allcontent2($ac['below'], "2")."</ul>"; if ($level == "1") $toR .= ""; }
}
return $toR; } ?>
call like this
<?php echo '<ul class="menu">'; echo stg_allcontent2(menu_tree_all_data($menu_name
= 'menu-header', $item = NULL)); echo '</ul>'; ?>
This may help you: http://drupal-translation.com/content/translating-block-contents#
UPDATE: the t() function allows you to pass in the language code to use.

Resources